数据结构OJ题

news/2024/11/24 13:56:37/

目录

1.字符串左旋 

2.字符串旋转结果

3.旋转数组

4.移除元素


本篇主要是讲解一些OJ题目。

1.字符串左旋 

字符串左旋

实现一个函数,可以左旋字符串中的k个字符

例如:

ABCD左旋一个字符得到BCDA

ABCD左旋两个字符得到CDAB

方法1【暴力求解】

  • 翻转1个字符
  1. 创建一个中间变量tmp,用于存储翻转的字符
  2. 把后面的字符向前覆盖移动
  3. 把tmp存储的字符放到结尾
  • 翻转k个字符,循环k次即可 
  • 注意如果旋转超出数组的元素个数范围,需要现处理一下。k=%len
#include<stdio.h>
void left_move(char* arr, int sz,int k)
{int i = 0;for (i = 0; i < k; i++)//k次{//一次翻转char tmp = 0;//1.tmp = *arr;int j = 0;//2.for (j = 0; j < sz - 2; j++){arr[j] = arr[j + 1];}arr[sz - 2] = tmp;//3.}
}
int main()
{char arr[] = "ABCDEF";int sz = sizeof(arr) / sizeof(arr[0]);//计算了\0int k = 0;scanf_s("%d", &k);k = k % (sz - 1);left_move(arr, sz,k);printf("%s", arr);return 0;
}


方法2【三步翻转】

  • 左边逆序
  • 右边逆序
  • 整体逆序
  • 封装一个逆序字符串的函数,传不同的起尾位置,调用三次函数即可
  • 注意如果旋转超出数组的元素个数范围,会造成数组越界的问题,需要现处理一下。k=%len
#include<stdio.h>
//逆序字符串函数
void reverse(char* begin, char* end)
{while (begin < end){char tmp = 0;tmp = *begin;*begin = *end;*end = tmp;begin++;end--;}
}
int main()
{char arr[] = "ABCDEF";int sz = sizeof(arr)/sizeof(arr[0]);int k = 0;scanf_s("%d", &k);k = k % (sz - 1);//必须有不然会数组越界reverse(arr, arr + k-1);reverse(arr + k, arr + sz - 2);reverse(arr, arr + sz - 2);printf("%s", arr);return 0;
}


2.字符串旋转结果

字符串旋转结果

写一个函数,判断一个字符串是否为另外一个字符串旋转之后的字符串。

例如:

给定s1= AABCD和s2 = BCDAA,返回1

给定s1=abcd和s2=ABCD,返回0

方法1【暴力求解】

  • 旋转1次比较1次
  • 把所有结果都列出来一一比较,如果没有那就返回0.
  • 注意:如果两个数组的长度不一样,是肯定不会旋转得到的,需要处理一下。
#include<stdio.h>
#include<string.h>
#include<assert.h>
int is_left_move(char* arr1, const char* arr2)
{assert(arr1 && arr2);int len1 = strlen(arr1);int len2 = strlen(arr2);if (len1 != len2){return 0;}int i = 0;//这里如果用while  len是变化的for(i=0;i<len1;i++){//一次翻转char tmp = 0;//1.tmp = *arr1;int j = 0;//2.for (j = 0; j < len1 - 1; j++){arr1[j] = arr1[j + 1];}arr1[len1 - 1] = tmp;//3//判断if (strcmp(arr1, arr2) == 0){return 1;}}return 0;
}
int main()
{char arr1[] = "ABCDEF";char arr2[] = "CDEFAB";int ret=is_left_move(arr1, arr2);if (ret == 1){printf("YES");}else{printf("NO");}return 0;
}

 


方法2【追加找子串 】

  • 把原字符串数组arr1追加,这样翻转所有的可能性都在追加字符串里
  • 再去arr1追加字符串里找子串arr2,看是否和要比较字符串数组arr2,相符号的。
  • 注意:如果两个数组的长度不一样,是肯定不会旋转得到的,需要处理一下。
#include<stdio.h>
#include<string.h>
#include<assert.h>
int is_left_move(char* arr1, const char* arr2)
{assert(arr1 && arr2);int len1 = strlen(arr1);int len2 = strlen(arr2);if (len1 != len2){return 0;}int len = strlen(arr1);strncat(arr1, arr1, len);if (strstr(arr1, arr2) == NULL)return 0;elsereturn 1;
}
int main()
{char arr1[] = "ABCDEF";char arr2[] = "CDEFAB";int ret=is_left_move(arr1, arr2);if (ret == 1){printf("YES");}else{printf("NO");}return 0;
}


3.旋转数组

给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。

输入: nums = [1,2,3,4,5,6,7], k = 3
输出: [5,6,7,1,2,3,4]
输入:nums = [-1,-100,3,99], k = 2
输出:[3,99,-1,-100]

方法1【暴力求解】

同上

时间复杂度:O(N^2)

#include<stdio.h>
#include<string.h>
#include<assert.h>
void right_move(char* arr,int k)
{assert(arr);int len = strlen(arr);k%=len;int i = 0;for (i = 0; i < k; i++){int j = 0;char tmp = arr[len - 1];for (j = len-1; j >0; j--){arr[j] = arr[j -1];}*arr = tmp;}
}
int main()
{char arr[] = "ABCDEF";int k = 0;scanf("%d", &k);right_move(arr,k);printf("%s", arr);return 0;
}

 


方法2【三步翻转】

界限:需要右旋&不需要右旋的逆置,整体逆置

时间复杂度:O(N) 

#include<stdio.h>
//逆序字符串函数
void reverse(char* begin, char* end)
{while (begin < end){char tmp = 0;tmp = *begin;*begin = *end;*end = tmp;begin++;end--;}
}
int main()
{char arr[] = "ABCDEF";int len = strlen(arr);int k = 0;scanf_s("%d", &k);k = k % len;//必须有不然会数组越界reverse(arr,arr+len-k-1);reverse(arr+len-k,arr+len-1);reverse(arr,arr+len-1);printf("%s", arr);return 0;
}

方法3【以时间换空间】

 


4.移除元素

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

输入:nums = [3,2,2,3], val = 3
输出:2, nums = [2,2]
解释:函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。你不需要考虑数组中超出新长度后面的元素。例如,函数返回的新长度为 2 ,而 nums = [2,2,3,3] 或 nums = [2,2,0,0],也会被视作正确答案。

方法1【暴力求解】

方法2【以空间换时间】

方法3【方法2的优化】


【暴力求解】&【三步翻转】 

【注意】 

  • len&sz
  • 指针&数组下标
  • 如果找错了位置或者减少了都会发生错误❌

✔✔✔✔✔最后,感谢大家的阅读,若有错误和不足,欢迎指正! 棠棣

代码---------→【唐棣棣 (TSQXG) - Gitee.com】

联系---------→【邮箱:2784139418@qq.com】


http://www.ppmy.cn/news/1182042.html

相关文章

PS 安装教程 2022版(全网最详细图文教程)

目录 一.简介 二.安装步骤 软件&#xff1a;PS版本&#xff1a;2022语言&#xff1a;简体中文大小&#xff1a;2.83G安装环境&#xff1a;Win10&#xff08;1903&#xff09;及以上版本&#xff0c;64位操作系统硬件要求&#xff1a;CPU2.0GHz 内存4G(或更高&#xff0c;不支…

Python学习笔记--类的定义和调用

二、类的定义和调用 1、怎么理解类&#xff1f; 类是什么&#xff1f; 个人认为理解类&#xff0c;最简单的方式就是&#xff1a;类是一个变量和函数的集合。 可以看下下面的这张图。 这张图很好的诠释了类&#xff0c;就是把变量和函数包装在一起。 当然我们包装也不是毫…

Windows找不到文件xxxxx.exe。请确认文件名是否正确后,再试一次

问题现象&#xff1a; Win11系统&#xff0c;每次重启后报如下错误&#xff0c;Windows找不到文件xxxxx.exe。请确认文件名是否正确后&#xff0c;再试一次 w10升级w11后出现 问题原因&#xff1a; xxx文件丢失&#xff0c;不知道是归属于谁的&#xff0c;怀疑是升级给弄丢…

express session JWT JSON Web Token

了解 Session 认证的局限性 Session 认证机制需要配合 cookie 才能实现。由于 Cookie 默认不支持跨域访问&#xff0c;所以&#xff0c;当涉及到前端跨域请求后端接口的时候&#xff0c;需要做很多额外的配置&#xff0c;才能实现跨域 Session 认证。 注意&#xff1a; 当前端…

电子学会C/C++编程等级考试2023年05月(四级)真题解析

C/C等级考试&#xff08;1~8级&#xff09;全部真题・点这里 第1题&#xff1a;怪盗基德的滑翔翼 怪盗基德是一个充满传奇色彩的怪盗&#xff0c;专门以珠宝为目标的超级盗窃犯。而他最为突出的地方&#xff0c;就是他每次都能逃脱中村警部的重重围堵&#xff0c;而这也很大程度…

C++系列之list的模拟实现

&#x1f497; &#x1f497; 博客:小怡同学 &#x1f497; &#x1f497; 个人简介:编程小萌新 &#x1f497; &#x1f497; 如果博客对大家有用的话&#xff0c;请点赞关注再收藏 &#x1f31e; list的节点类 template struct list_Node { public: list_Node* _prev; list_…

学游戏设计有前途吗优漫教育

很多同学对游戏设计感兴趣&#xff0c;但又不了解这个行业具体怎么样&#xff0c;现在学习的话还有前途吗&#xff1f;都包括什么&#xff1f;下面就来跟大家详细介绍下&#xff01; 学游戏设计有前途吗   答案当然是肯定的&#xff0c;我们之所以会产生这样困惑和担忧&a…

react中使用监听

在 React 中&#xff0c;您可以使用 addEventListener 函数来监听事件。以下是一个示例&#xff1a; import React, { useRef, useEffect } from react;function App() {const inputRef useRef(null);useEffect(() > {inputRef.current.addEventListener(input, handleInp…