leetcode[Find All Numbers Disappeared in an Array]

来源:互联网 发布:淘宝商城包 编辑:程序博客网 时间:2024/06/08 01:14

错误解法(用了辅助空间,n值很大时会超时):

public class Solution {    public List<Integer> findDisappearedNumbers(int[] nums) {        List<Integer> list = new ArrayList<>();        for(int i = 0; i < nums.length; i++){//先整理出长度为n的nums应该有的元素        list.add(i + 1);        }                for(int i = 0; i < nums.length; i++){//遍历nums,从list去除nums中现有的,留下的就是还缺少的元素        list.remove(new Integer(nums[i]));//移除Integer才是移除元素,移除int移动的是下标        }                return list;    }}

解法一:

public class Solution {    public List<Integer> findDisappearedNumbers(int[] nums) {    //既然是因为nums里面有重复元素,导致少了一些应该有的元素    //那么就遍历nums,将值与数组索引对应起来,之后看哪些索引没有被用到,就说明是缺少的元素    //比如nums里面有元素4,那么正确应该对应的索引就是3(因为3=4-1),nums[3] = 4    for(int i = 0; i < nums.length; i++){    //nums[nums[i] - 1] = -1;//标记存在的元素,因为正确里面的元素范围是1到n,这里就用-1来标记    //上面那种方式不对,因为如果有重复元素的话就乱套了,正确方式见下面            int val = Math.abs(nums[i]) - 1;//如果nums[i]之前被标记过了,那么它现在就是负数,所以要取绝对值            if(nums[val] > 0) {//之前标记过的就不标记了                nums[val] = -nums[val];//标记存在的元素,用负数来,这样是为了之后遇到重复元素也能正确判断            }    }        List<Integer> list = new ArrayList<>();        for(int i = 0; i < nums.length; i++){    if(nums[i] > 0){    list.add(i + 1);    }    }        return list;    }}

解法二(也是利用标记的思路,标记方式和解法一有区别):

public class Solution {public List<Integer> findDisappearedNumbers(int[] nums){        List<Integer> res = new ArrayList<>();        int n = nums.length;                for(int i = 0; i < nums.length; i++){        //用余数标记,避免了负数需要取绝对值调整的情况        nums[(nums[i]-1) % n] += n;        }                for(int i = 0; i < nums.length; i++){        if(nums[i] <= n){//被标记过的都大于n了            res.add(i+1);        }        }                return res;    }}

阅读全文
0 0