两道关于复杂度的LeetCode OJ题
- 消失的数字
- 轮转数组
代码:C语言
点击前往LeetCode查看消失的数字
要求 :时间复杂度要在O(n)内
- malloc一个额外的个数为n+1的数组,并全部初始化为-1。
- 遍历要输入的数据,这个数是多少,就填写到该数组对应位置。
- 再遍历一遍该数组,哪个位置是-1,那么哪个位置的下标就是缺失的数字。
ps:Drawio的绘图很不错!!!有需要的可以导Microsoft Store搜索应用Drawio,直接下载正版。
- 时间复杂度:O(n),符合题目要求
- 空间复杂度:O(n)
- 代码部分也比较简单,这里就不实现了。
- 使用异或,这里先给大家补充一下异或的知识。
- 什么是异或?
在逻辑学中,逻辑算符异或(exclusive or)是对两个运算元的一种逻辑析取类型,符号为 XOR 或 EOR 或 ⊕(编程语言中常用^)。
但与一般的逻辑或不同,异或算符的值为真仅当两个运算元中恰有一个的值为真,而另外一个的值为非真。转化为命题,就是:“两者的值不同。”或“有且仅有一个为真。”- 异或的特性:
- 相同的两个数异或的结果为0。
- 异或不分顺序。按位异或,相同为0,相异为1。
- 0和任何数异或结果为该数本身
下面进入正题,解决思路如下:
- 创建一个变量x,并赋初值为0
- x跟输入的数据都异或一遍
- x和0~n之间的数都异或一遍,最后的x即为缺失的数字
C语言代码实现如下:
int missingNumber(int* nums, int numsSize) {
int x = 0;
for (int i = 0; i < numsSize; ++i)
{
x ^= nums[i];
}
for (int j = 0; j < numsSize+1; ++j)
{
x ^= j;
}
return x;
}
- 时间复杂度:O(n)
- 空间复杂度:O(1)
点击前往LeetCode查看轮转数组
轮转数组(旋转数组)要求如下:
- 想出三种不同的解决方法
- 时间复杂度O(n)
- 空间复杂度O(1)
- 每次旋转一个
- 旋转K次
- 时间复杂度:O(N^2)
- 空间复杂度:O(1)
- 不符合要求(过不了OJ)
以空间换时间
- 时间复杂度:O(n)
- 空间复杂度:O(n)
- 不符合要求(但能过OJ)
- 原地逆置
- 时间复杂度:O(n)
- 空间复杂度:O(1)
- 符合题意✔✔✔,是最优解法也最难想到
C语言代码实现如下:
int* reverse(int* nums, int left, int right)
{
while (left < right)
{
int tmp = nums[left];
nums[left] = nums[right];
nums[right] = tmp;
left++;
right--;;
}
return nums;
}
void rotate(int* nums, int numsSize, int k) {
k %= numsSize;
reverse(nums, numsSize - k, numsSize - 1);
reverse(nums, 0, numsSize - k - 1);
reverse(nums, 0, numsSize - 1);
}
学习记录:
- 本篇整理于2022.6.21
- 如果有错误的地方请多多指教