LeetCode:442. Find All Duplicates in an Array

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,数列中的所有数都属于1-n之间。
2)数列中的数有些出现1次,有些出现2次。
问题:求出数列中出现两次的所有数。
分析:
看到题目第一个想法就是异或,两个相同的数异或为0。但是要求不允许使用额外的空间,而且异或操作无法知道有几个数重复,重复的是哪几个数。
再根据题目给出的第一个条件,1 <=a[i] <=n,然后可以想到a[i]可以作为下标。再结合异或的思想,构造算法:
扫描数组,把a[i]作为下标,a[a[i]]*=-1; 如果a[a[i]]>0;说明已经出现过一次,count++;
代码如下:

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

补充:之前做过一个很有意思的笔试题,也是利用了异或的思想,在这里大略记录一下:
有个监狱关押了10个犯人,有一天监狱长心血来潮让这些犯人玩一个游戏,让这些人排成一列纵队,让每个犯人戴着一顶帽子,帽子的颜色只有黑和白,每个人只能看到其他人帽子的颜色而无法看到自己的。监狱长从后向前依次问犯人他自己帽子的颜色,如果答对了,该犯人就可以获得自由。在玩游戏的前一天犯人们有一晚上的商量时间。问应该如何制定策略,使得释放的犯人数目最多?
答案:
制定策略:每个犯人都计算其前面所有人帽子颜色的异或值,第一个被问到的犯人回答他计算的异或值,然后后面被问到的犯人则利用后一个人的回答以及本人计算的异或值,得到自己帽子的颜色,一定是正确的回答。
按照这样的策略,必然至少n-1个犯人能够得到自由,只有排在最后面的犯人的存活率是50%。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章