LeetCode第448题 Find All Numbers Disappeared in an Array解决办法

 

题目

Given an array of integers where 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others appear once.

Find all the elements of [1, n] inclusive that do not appear in this array.

Could you do it without extra space and in O(n) runtime? You may assume the returned list does not count as extra space.

Example:


Input: [4,3,2,7,8,2,3,1]

Output: [5,6]


解决办法

这个问题的基本要求是:

1.对于一个给定的数组,大小为n,数组中的元素为1 ≤ a[i] ≤ n ,其中存在部分元素大小相同的情况,要求查找在1~n中有哪些数在数组中不存在。

2.除给定的数组和作为返回值的List外,不在分配额外的存储空间,且时间复杂度为O(n)。(PS.非强制要求)

方法一 [Time Limit Exceeded]

class Solution {
    public List<Integer> findDisappearedNumbers(int[] nums) {
        List<Integer> list = new ArrayList<Integer>();
        for(int i=1;i<=nums.length;i++){
            if(!isExist(i,nums))
                list.add(i);
        }
        return list;
    }
    
    public boolean isExist(int i,int[] nums){
        for(int j=0;j<nums.length;j++){
            if(nums[j]==i)
                return true;
        }
        return false;
    }
}

在这个方法中,我们采用线性搜索算法,这个算法比较简单,通过检查数组中的每个元素,一次一个地按顺序查找并判断特定值是否在列表中,直到找到所需的元素。如果找到一个对应元素,则返回true, 如果没有,就继续执行。在程序结束时返回false。

复杂性分析

  • 时间复杂度: O(n ^ 2)

  • 空间复杂度: O(1)。只使用了恒定的空间。

方法二 [Accepted]

class Solution {
    public List<Integer> findDisappearedNumbers(int[] nums) {
         List<Integer> list = new ArrayList<Integer>();
         Set<Integer> set = new HashSet<Integer>();
         for(int i=1;i<=nums.length;i++){
             set.add(i);
         }
         for(int num:nums){
             set.remove(num);
         }
         list.addAll(set);
         return list;
     }
}

通过将1~n添加到set集合中,然后再将数组中存在的元素从set中remove掉,剩余的元素即1~n中不存在于数组里的数。

复杂性分析

  • 时间复杂度: O(n )

  • 空间复杂度: O(n)。创建Set集合消耗了额外的空间。

方法三 [Accepted]

class Solution {
    public List<Integer> findDisappearedNumbers(int[] nums) {
		List<Integer> res = new ArrayList<Integer>();
		for(int i=0;i!=nums.length;i++){
			nums[Math.abs(nums[i])-1] = -Math.abs(nums[Math.abs(nums[i])-1]);
		}
		for(int i=0;i!=nums.length;i++){
			if(nums[i]>=0){
				res.add(i+1);
			}
		}
		return res;
	}
}

最巧妙的一个算法,通过将数组中指定位置的元素的值取反,最后通过值的正负来判断1~n中有哪些数不存在于数组中。比如nums[1]==4,则将数组中第四个元素取反,即nums[3] = -Math.abs(nums[3])。如果最后数组中nums[5]的值为正,即数组中第六个元素为正,就说明数组中不存在6。

复杂性分析

  • 时间复杂度: O(n)

  • 空间复杂度: O(1)。只使用了恒定的空间。

猜你喜欢

转载自blog.csdn.net/qq_22408539/article/details/82634420