41. 缺失的第一个正数
给你一个未排序的整数数组,请你找出其中没有出现的最小的正整数。
题解
要求空间复杂度O(1)。前不久刚做了一道循环排列的题,所以看见“就地”两个字,秒懂: 将数字放到对应的位置上
有个特殊的样例,
nums[i] - 1
可能会超出int
的范围
class Solution {
public:
int firstMissingPositive(vector<int>& nums) {
int n = nums.size();
for (int i = 0; i < n; ++i) if (nums[i] >= 0) nums[i]--;
for (int i = 0; i < n; ++i) {
int pos = nums[i];
while(pos >= 0 && pos < n && pos != nums[pos]) swap(pos, nums[pos]);
}
int ans = n + 1;
for (int i = 0; i < n; ++i) if (nums[i] != i) {
ans = i + 1;
break;
}
return ans;
}
};
287. 寻找重复数
给定一个包含 n + 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数。假设只有一个重复的整数,找出这个重复的数。
题解一
要求空间复杂度O(1)、时间复杂度小于O( n 2 n^2 n2)、不能更改原数组。二分枚举答案,遍历整个数组,如果小于或者等于枚举的答案的个数大于枚举的答案,说明左半段出现了重复,否则,说明右半段出现了重复。
妙啊!原味:https://leetcode-cn.com/problems/find-the-duplicate-number/solution/er-fen-fa-si-lu-ji-dai-ma-python-by-liweiwei1419/
class Solution {
public:
int findDuplicate(vector<int>& nums) {
int n = nums.size();
int l = 1, r = n;
// 时间换空间,有点儿意思
while(l < r) {
int mid = (l + r) >> 1; // 枚举答案
int cnt = 0;
for (int num: nums) if (num <= mid) cnt++;
if (cnt > mid) r = mid;
else l = mid + 1;
}
return l;
}
};
题解二
oooooorz,还可以用二进制考虑。思想就一句话:如果一个数是重复的,那么对应的二进制位中1的个数肯定比原来多,因为重复了嘛。
详细讲解:https://leetcode-cn.com/problems/find-the-duplicate-number/solution/xiang-xi-tong-su-de-si-lu-fen-xi-duo-jie-fa-by–52/
// beautiful code
class Solution {
public:
int findDuplicate(vector<int>& nums) {
int n = nums.size();
int ans = 0;
for (int i = 0; i < 32; ++i) {
int a = 0, b = 0;
int mask = 1 << i;
for (int j = 0; j < n; ++j) {
if (nums[j] & mask) a++;
if (j & mask) b++;
}
if (a > b) ans += mask; // ans = ans | mask; is ok!
}
return ans;
}
};
// sad code
class Solution {
public:
int findDuplicate(vector<int>& nums) {
int n = nums.size();
int bit_cnt[40];
memset(bit_cnt, 0, sizeof(bit_cnt));
for (int num: nums) {
int t = 0;
while(num) bit_cnt[t++] += (num & 1), num >>= 1;
}
int bit_tot[40];
memset(bit_tot, 0, sizeof(bit_tot));
for (int i = 1; i < n; ++i) {
int t = 0, num = i;
while(num) bit_tot[t++] += (num & 1), num >>= 1;
}
int ans = 0;
for (int i = 0; i < 32; ++i) if (bit_tot[i] < bit_cnt[i]) ans += (1 << i);
return ans;
}
};
题解三
n + 1 n + 1 n+1个