校招常用Leecode题目详解(旋转数组和消失的数字)

旋转数组:https://leetcode.cn/problems/rotate-array/
消失的数字:https://leetcode-cn.com/problems/missing-number-lcci/

大家可以先看看题目,如果觉得自己秒会的请手动划走
校招常用Leecode题目详解(旋转数组和消失的数字)_第1张图片

旋转数组

思路一

旋转k次(下面用7个数字举例, K == 3)

校招常用Leecode题目详解(旋转数组和消失的数字)_第2张图片

代码实现

// 思路一
void rotate(int* nums, int numsSize, int k) {
	while(k--)
	{
		int tmp = nums[numsSize - 1];

		for (int i = numsSize - 1; i > 0; i++)
		{
			nums[i] = nums[i - 1];
		}
		nums[0] = tmp;
	}
}

相信这个不用多说,虽然这个思路容易想到,但是时间复杂度是(numsSize ^ k),但是空间复杂度只有O(1),所以这道题可以空间去换时间。

思路二

创建一个数组,先把后K个元素放入,然后再将其他元素一次放入
校招常用Leecode题目详解(旋转数组和消失的数字)_第3张图片

代码实现

// 思路二
void rotate(int* nums, int numsSize, int k){

    k = k % numsSize;
    int temp[numsSize];
    int j = 0;
    // 把nums数组中的后k个元素存入temp中
    for(int i = numsSize - k; i < numsSize; i++)
    {
        temp[j] = nums[i];
        j++;
    }

    // 把nums前面的numsSize - k    (4)个元素放到temp中
    for(int i = 0; i < numsSize - k; i++){
        temp[j] = nums[i];
        j++;
    }

    // 将temp里面的值赋到nums数组中
    for(j = 0; j < numsSize; j++)
    {
        nums[j] = temp[j];
    }
}

思路三

这个思路一般是想不到的(反正我没有),但是只有懂了实现起来就非常简单
校招常用Leecode题目详解(旋转数组和消失的数字)_第4张图片

代码实现

// 思路三
void reverse(int* nums, int begin, int end)
{
	while (begin < end)
	{
		int tmp = nums[begin];
		nums[begin] = nums[end];
		nums[end] = tmp;
        begin ++;
        end --;
	}
}
void rotate(int* nums, int numsSize, int k) {
    k %= numsSize;
	// 前numsSize - k个元素逆置
	reverse(nums, 0, numsSize - k - 1);
	// 后k个元素逆置
	reverse(nums, numsSize - k, numsSize - 1);
	// 数组全部元素逆置
	reverse(nums, 0, numsSize - 1);
}

消失的数字

思路一(求和)

先求出0 ~ numsSize的和,然后再算出nums数组内所有元素之和,然后相减

代码实现

int missingNumber(int* nums, int numsSize){
    // 先求出 0 ~ numSize 的和
    int ret = (0 + numsSize) * (numsSize + 1) / 2;
    int sum = 0;
    int i = 0;
    // 求出原本数组内的和
    for(i = 0; i < numsSize; i++)
    {
        sum += nums[i];
    }

    return (ret - sum);
}

思路二(异或)

首先我们得清楚异或(^)的原理:相同为0,相异为1,并且0任何数都等它本身,即(假设ab不相等)a ^ a = 0,a ^ b = b ^ a,0 ^ a = a
所以

首先异或上0-n的数,即ret = 012n
然后对数组元素异或,nums[0]nums[1]…^nums[numsSize-1]
然后异或这二者,即 ret = 0123nnums[0]nums[1]…^nums[numsSize-1]
最终ret就为消失的数字
打个比方:nums[] = {2,3,4,1,6}
ret = 0 ^ 1 ^ 2 ^ 3 ^ 4 ^ 5 ^ 6 ^ 2 ^ 3 ^ 4 ^ 1 ^ 6 = 5

作者:nostalgia-k
链接:https://leetcode.cn/problems/missing-number-lcci/solution/by-nostalgia-k-7mqr/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

代码实现

int missingNumber(int* nums, int numsSize){
//异或
int ret = 0;
//先异或0-n的所有数
for(int i = 0; i <= numsSize; ++i){
ret ^= i;
}
//再将ret与数组所有数异或
for(int i = 0; i < numsSize; ++i){
ret ^= nums[i];
}
return ret;
}

作者:nostalgia-k
链接:https://leetcode.cn/problems/missing-number-lcci/solution/by-nostalgia-k-7mqr/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

这道题第二种思路我也没想到,大家可以看一看别人的思路

你可能感兴趣的:(算法,leetcode,数据结构)