问题
以41为例
题解
- 题目的关键在于时间复杂度以及空间复杂度,可以借鉴448题,利用下标对下标对应元素的交换原地降低时间复杂度。
- 整体思路:
- 交换的目的为了让下标上的元素和下标一样,第一个不相等的下标即为第一个缺失的正数
- 示例2来说,为了方便比较,先对每个元素做-1操作:
2 3 -2 0
0 1 2 3
第一次交换,由于0上方的元素不是0,因此,让2交换到下标为2的地方
-2 3 2 0
0 1 2 3
第二次交换,由于0上方的数字不在0~n之间,因此移动枚举的指针,继续往后遍历,同理第一次交换
-2 0 2 3
0 1 2 3
第三次交换,1上方是0,继续与下标0上方的元素进行交换
0 -2 2 3
0 1 2 3
由于下标2和3已经满足下标和下标对应的元素相等的条件,继续枚举到数组尾部
最后遍历数组,第一个下标和下标对应元素不等的下标+1就是我们要找的第一个缺失的正数,也就是这里的2
class Solution {
public int firstMissingPositive(int[] nums) {
for(int i = 0; i < nums.length; i ++){
nums[i] -= 1;
}
for(int i = 0; i < nums.length; i ++){
if(nums[i] == i){
continue;
}
while(nums[i] != i)
{
if(nums[i] >= 0 && nums[i] < nums.length && nums[nums[i]] != nums[i]){
exch(nums, nums[i], i);
}else{
break;
}
}
}
for(int i = 0; i < nums.length; i ++){
if(nums[i] != i) {
return i + 1;
}
}
return nums.length + 1;
}
public void exch(int[] nums, int a, int b){
int temp = nums[a];
nums[a] = nums[b];
nums[b] = temp;
}
}
同理于41题,448题也是利用同样的交换方法,这种方法也是一种哈希算法,也就是nums[i]==i
class Solution {
public List<Integer> findDisappearedNumbers(int[] nums) {
List<Integer> res = new LinkedList();
for(int i = 0; i < nums.length; i ++){
nums[i] -= 1;
}
for(int i = 0; i < nums.length; i ++){
if(nums[i] == i){
continue;
}
while(nums[i] != i)
{
if(nums[nums[i]] != nums[i]){
exch(nums, nums[i], i);
}else{
break;
}
}
}
for(int i = 0; i < nums.length; i ++){
if(nums[i] != i) {
res.add(i + 1);
}
}
return res;
}
public void exch(int[] nums, int a, int b){
int temp = nums[a];
nums[a] = nums[b];
nums[b] = temp;
}
}