一、消失的数字
. - 力扣(LeetCode)
本题要求的时间复杂度是O(n) ,所以我们不能用循环嵌套;
解法一:
int missingNumber(int* nums, int numsSize){int sum1=0;for(int i=0;i<=numsSize;i++){sum1+=i;}int sum2=0;for(int i=0;i<numsSize;i++){sum2+=nums[i];}return sum1-sum2;
}
先把0到n的数字加起来,再把原数组里面的所有元素加起来,再用前者减去后者,得出的就是消失的数字;
解法二:
int missingNumber(int* nums, int numsSize){int x=0;for(int i=0;i<=numsSize;i++){x^=i;}for(int i=0;i<numsSize;i++){x^=nums[i];}return x;
}
相同数字互相异或得到0,0和一个非零数字异或得到这个非零数字;先把原本没有消失的有序数列互相异或一遍,再和这个消失了一个数字的数组里面的数据异或一遍,因为相同的数字异或之后为0,没有消失的数据一定是成对出现的,那么最终的结果就是有序数列里面单独剩下的数据,就是消失的数字。
二、轮转数组
. - 力扣(LeetCode)
解法一:
void rotate(int* nums, int numsSize, int k) {int time=k%numsSize;for(int i=0;i<time;i++){int right=nums[numsSize-1];for(int j=numsSize-2;j>=0;j--){nums[j+1]=nums[j];}nums[0]=right;}
}
这个解法的时间复杂度是O(n^2);假设数组中的元素个数是n,time最坏是n-1,最好是0,嵌套在里面的循环是n-1次,所以是O(n^2);
每次先保留数组的最后一个数据,再把除了这个数据的前面的数据整体向后移动一格,最后再把下标为0的数据赋值为保留的那个最后的数据;
这种方法可行,但是再LeetCode上面无法通过,超出时间限制;
解法二:
void reverse(int* arr,int len)
{int left = 0;int right = len - 1;while (left <= right){int tmp = arr[left];arr[left] = arr[right];arr[right] = tmp;left++;right--;}
}
void rotate(int* nums, int numsSize, int k) {k%=numsSize;reverse(nums, numsSize - k);reverse(nums+(numsSize-k), k);reverse(nums, numsSize);
}
分段逆置,再整体逆置;
解法三:
void _rotate(int* nums,int numsSize,int k, int* tmp)
{k%=numsSize;int n=numsSize;memcpy(tmp,nums+n-k,sizeof(int)*k);memcpy(tmp+k,nums,sizeof(int)*(n-k));memcpy(nums,tmp,sizeof(int)*n);
}
void rotate(int* nums, int numsSize, int k) {int* tmp=(int*)malloc(sizeof(int)*numsSize);_rotate(nums,numsSize,k,tmp);
}
重新开辟一个数组,使用memcpy内存操作函数去把逆置的数据从nums里面copy到tmp里面,最终再把tmp里面的所有数据copy到nums里面,最终的不能直接写nums=tmp,要用内存操作函数,这样才能让nums在内存上发生改变。