442. Find All Duplicates in an Array[Medium]

来源:互联网 发布:java设计用户管理 编辑:程序博客网 时间:2024/06/06 05:20

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?

题目大意:
  给出一个包含从1~n的数组,数组中的元素最多只出现2次,求出现两次的所有元素。

解题思路:
  正负值标记法:
  首先假设有一个数组nums = {4,3,2,7,8,5,6,1},里面元素均不重复。
  则很容易发现,当数组元素均不重复时,以数组元素为下标,对nums数组做二次映射的时候,里面的数组元素,均只被访问了一次。
  即首先: int index = nums[i]-1(i∈[0,7]),为了与数组下标统一
  二次映射时 nums[index]均在nums中只被访问一次,这是因为每个index都是唯一且不重复的,如果在二次映射访问过程中,index出现重复,则在遍历nums[index]时,重复的元素一定会被访问两次。
  比如数组 nums2 = {4,3,2,7,8,2,3,1},由于其中元素2,3均出现两次,所以在nums2[index]中,数组元素会被重复访问。此时,在第一次访问数组元素时,可以将首次访问的元素设置为其相反数,当第二次访问该元素时,判断其值是否小于0,若小于0,则说明前一次遍历已经访问到了这个元素,可以进一步说明,这个元素为重复元素。
  

public List<Integer> findDuplicates(int[] nums) {        List<Integer> newList = new ArrayList<Integer>();     // 创建list用于存储重复元素        for(int i=0;i<nums.length;i++){             int index =Math.abs(nums[i]);             // 取数组元素的绝对值,保证第一次访问前,是正数           if(nums[index-1] >0){                     nums[index-1] = - nums[index-1];            }else{                   // 如果二次映射访问的值小于0,则说明出现重复                    newList.add(Math.abs(nums[i]));             }        }        return newList;    }
原创粉丝点击