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%。

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