一、消失的数字
. - 力扣(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在内存上发生改变。