参考思路
⏰ 时间复杂度: O ( n ) O(n) O(n)
空间复杂度: O ( 1 ) O(1) O(1)
class Solution {
public int firstMissingPositive(int[] nums)
{
int n = nums.length;
//目标:nums[i] 存放 i+1 是正确的,表示存在 i+1 这个数
for (int i = 0; i < n; i++)
{
if (i + 1 == nums[i])//无误跳过
continue;
int x = nums[i];
// 在 [1,n] 之内的数就放在 nums[x-1]的位置
if (x >= 1 && x <= n && x != nums[x - 1])
{
swap(nums, i, x - 1);
i--;//交换后当前位置 i 是一个新的数,i-- 再次处理
}
}
// 当出现第一个 nums[i] != i+1 时,表示 (i+1)不存在,即缺失的最小正整数
for (int i = 0; i < nums.length; i++)
if (i + 1 != nums[i])
return i + 1;
return n + 1;
}
// 交换数组 a 中 下标 i ,j 上的值
private void swap(int[] a, int i, int j)
{
if (i != j)
{
a[i] ^= a[j];
a[j] ^= a[i];
a[i] ^= a[j];
}
}
}
⏰ 时间复杂度: O ( n ) O(n) O(n)
空间复杂度: O ( n ) O(n) O(n)
public int firstMissingPositive(int[] nums) {
int length = nums.length;
int bit[] = new int[(length - 1) / 32 + 1];
for (int i = 0; i < nums.length; i++) {
int digit = nums[i];
//数组必须在1到length之间才有效
if (digit >= 1 && digit <= length) {
int index = (digit - 1) / 32;
bit[index] |= (1 << ((digit - 1) % 32));
}
}
//最后在执行一遍循环,查看对应位置的元素是否正确,如果不正确直接返回
for (int i = 0; i < nums.length; i++) {
if ((bit[i / 32] & (1 << (i % 32))) == 0)
return i + 1;
}
return length + 1;
}