无论你觉得自己多么的不幸,永远有人比你更加不幸。💓💓💓
目录
说在前面
题目一:消失的数字
题目二:轮转数组
SUMUP结尾
说在前面
dear朋友们大家好!💖💖💖数据结构的学习离不开刷题,我们之前介绍了简单的复杂度相关的分析,那今天我们就紧随其后刷上几道题,对其进行巩固和联系吧。当今天我们的题目主要来自LeetCode。
👇👇👇
友友们!🎉🎉🎉点击这里进入力扣leetcode学习🎉🎉🎉
以下是leetcode题库界面:
题目一:消失的数字
题目链接:面试题 17.04. 消失的数字 - 力扣(LeetCode)
题目描述:
题目分析:
思路1:将1到n的数进行求和,再减去数组中的每个元素,剩下的数就是消失的数字。
求和序列:S= 1 + 2 + 3 + ... (i-1) + i + (i+1) + ... + (n-1) + n
数组元素:{1,2,3,...i-1,i+1,...,n - 1,n + 1}
可以发现,如果将数组元素和求和序列的各项进行对比,发现求和序列的和S比数组元素的和多i,而这个i就是我们需要求的消失的数字。
代码如下:
int missingNumber(int* nums, int numsSize) {int sum = 0;for (int i = 0; i <= numsSize; i++){sum += i;//1到n求和}for (int i = 0; i < numsSize; i++){sum -= nums[i];//减去数组中的每个元素}return sum;
}
思路2:用0异或从1到n的所有数字,再异或数组nums中的所有元素。
根据0异或任意数 x 都得 x ,且 x ^ x = 0,所以这样做只有数组nums中所缺少的那个数被异或了一次,结果显然就是它。
代码如下:
int missingNumber(int* nums, int numsSize) {int ret = 0;for (int i = 0; i <= numsSize; i++){ret ^= i;//用0从1到n异或}for (int i = 0; i < numsSize; i++){ret ^= nums[i];//再异或数组中的每个元素}return ret;
}
上面两种算法的复杂度都是O(N),是可行的,但是思路1在N非常大的时候可能存在溢出风险。
题目二:轮转数组
题目链接:189. 轮转数组 - 力扣(LeetCode)
题目描述:
题目分析:
思路1:将数组分割成两部分,一部分从0到n-k-1(前n-k个),另一部分从n-k到n-1(后k个),然后将这两部分分别逆置,最后再整体逆置。
举例:
nums = {1,2,3,4,5,6,7} k = 4
所以,我们可以封装一个单独的函数ReverseRange,用来逆置一个数组在一定范围的元素。
代码如下:
//逆置函数
void ReverseRange(int* nums, int left, int right) {while (left <= right)//逆置[left,right]内的元素{int temp = nums[left];nums[left] = nums[right];nums[right] = temp;left++;right--;}
}//三段逆置
void rotate(int* nums, int numsSize, int k) {k %= numsSize;ReverseRange(nums, 0, numsSize - k - 1);//逆置前n-k个ReverseRange(nums, numsSize - k, numsSize - 1);//逆置后k个ReverseRange(nums, 0, numsSize - 1);//整体逆置
}
这个方法的时间复杂度是O(N)。
思路2:将利用memcpy函数将原数组nums的后k个拷贝到临时数组temp中,再将原数组nums的前n-k个继续拷贝到临时数组temp中,最后再将temp拷贝到nums中。
代码如下:
//将固定区间内的元素拷贝到临时数组temp中
void Reverse(int* nums, int numsSize, int k, int* temp) {k %= numsSize;int n = numsSsize;//用n代替sumsSize方便书写memcpy(temp, nums + N - k, k * sizeof(int));//拷贝后k个memcpy(temp + k, nums, (n - k) * sizeof(int));//拷贝前n-k个memcpy(nums, temp, n * sizeof(int));//将temp拷贝到nums中
}void rotate(int* nums, int numsSize, int k) {int temp[numsSize];//创建临时变量tempReverse(nums, numsSize, k, temp);//完成轮转数组的操作
}
这个方法的时间复杂度是O(N)。
SUMUP结尾
数据结构就像数学题,需要刷题才能对它有感觉。之后还会更新数据结构相关的练习题、面试题,希望大家一起学习,共同进步~
如果大家觉得有帮助,麻烦大家点点赞,如果有错误的地方也欢迎大家指出~