数组
方法1:交换
public int firstMissingPositive(int[] nums) {
int n = nums.length;
for (int i = 0; i < n; i++) {
//前两个条件是为了判断nums[i]是否在0-n范围内,防止index越界
//后一个是判断i 这个index(当前的值)和nums[i]-1这个index(标准位置)是否相等,
//标准位置:某个数nums[i] 落整个array的i-1的位置上
while (nums[i] > 0 && nums[i] <= n && nums[i] != nums[nums[i] - 1]) {
swap(nums, i, nums[i] - 1);
}
}
//判断第一个出现异常的数字
for (int i = 0; i < n; i++) {
if (nums[i] - 1 != i) {
return i + 1;
}
}
return n + 1;
//[3, 4, 4, -1, 1]->[1,4,3,4,-1] 异常的时index为1的数nums[1] 其值约为 (1+1=2)但是实际是4
//[3, 4, -1, 1] -->[1,-1,3,4]
//[3,4,-1,-2,1,5,16,0,2,0]-->[1,2,3,4,5,-1,16,0,-2,0]
}
private void swap(int[] nums, int m, int n) {
int temp = nums[m];
nums[m] = nums[n];
nums[n] = temp;
}方法2:BitSet
翻转方向和标记已经访问的点,是本题的关键
方法1:优先队列
方法2:快排
方法3:堆排序
方法1:Set
方法2:lambda
方法3:排序
方法1:标记
思路
我们也可以给nums[i] 加上「负号」表示数 i+1 已经出现过一次。具体地,我们首先对数组进行一次遍历。当遍历到位置 i 时,我们考虑 nums[nums[i]−1] 的正负性:
如果
nums[nums[i]−1]是正数,说明nums[i]还没有出现过,我们将nums[nums[i]−1]加上负号;如果
nums[nums[i]−1]是负数,说明nums[i]已经出现过一次,我们将 放入答案。
细节
由于
nums[i]本身可能已经为负数,因此在将nums[i]作为下标或者放入答案时,需要取绝对值。
方法2:交换
将442题的方法2修改下
Last updated