Woodyiiiiiii / LeetCode

My private record of Leetcode solution

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

LeetCode 442. Find All Duplicates in an Array

Woodyiiiiiii opened this issue · comments

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

Find all the elements that appear twice in this array.

Could you do it without extra space and in O(n) runtime?

Example:

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

Output:
[2,3]

一个数组中的元素是在1~n的范围内,并且有的出现两次,有的出现一次,要求找到出现两次的元素,并且时间复杂度在O(n),没有额外空间。

这道题的难点在于如何用有限的条件完成不用额外空间的算法。不用多余的空间,我们每次遍历对每个元素只能设置一个变量,显然是不足以完成题目条件的。那么,我们要注意到题目还有个限制条件:数组元素是在1~n的范围内,而且也要利用数组空间。

解法:将数组元素当作一个索引,因为数组元素的范围限制,那么按照该元素索引的数组元素做一个标志,如果是正数,代表该索引第一次使用,设置成相反数,如果是负数,说明当前索引已经被使用过,则加入到结果集合中。

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

关键:

  1. 完全利用题目条件
  2. 把元素当成索引,同时也当成标志位

参考资料: