自己解法
这个题由于是O(N)的时间复杂度加O(1)的空间复杂度,所以没啥思路,看了一眼题解,用hash的思路,但是没想明白,怎么才能在打标记的同时,还能不覆盖数组原本的值,后面又看了眼题解,才明白,先把负数都变成n+1后,用负号标记存在,且不改之前的绝对值,真是美妙的思路。
class Solution {
public int firstMissingPositive(int[] nums) {
int n = nums.length;
for (int i = 0; i < n; i++) {
if (nums[i] <= 0) {
nums[i] = n + 1;
}
}
for (int i = 0; i < n; i++) {
int m = Math.abs(nums[i]);
if (m < n + 1) {
nums[m - 1] = - Math.abs(nums[m - 1]);
}
}
for (int i = 0; i < n; i++) {
if (nums[i] > 0) {
return i + 1;
}
}
return n + 1;
}
}
官方解法
上面那个解法,已经是看过了官方解法了,下面贴另一种思路吧。
这种置换的思路也有想一点,自己想的也是双指针,不过是比较大小后交换,没什么用的感觉。这种解法是置换到对应的下标位置,其实和上面那种思路类似,还是上面的思路更清晰。
class Solution {
public int firstMissingPositive(int[] nums) {
int n = nums.length;
for (int i = 0; i < n; ++i) {
while (nums[i] > 0 && nums[i] <= n && nums[nums[i] - 1] != nums[i]) {
int temp = nums[nums[i] - 1];
nums[nums[i] - 1] = nums[i];
nums[i] = temp;
}
}
for (int i = 0; i < n; ++i) {
if (nums[i] != i + 1) {
return i + 1;
}
}
return n + 1;
}
}
网友评论