LeetCode oj 260. Single Number III (位運算)

260. Single Number III

 
 My Submissions
  • Total Accepted: 49443
  • Total Submissions: 103739
  • Difficulty: Medium

Given an array of numbers nums, in which exactly two elements appear only once and all the other elements appear exactly twice. Find the two elements that appear only once.

For example:

Given nums = [1, 2, 1, 3, 2, 5], return [3, 5].

Note:

  1. The order of the result is not important. So in the above example, [5, 3] is also correct.
  2. Your algorithm should run in linear runtime complexity. Could you implement it using only constant space complexity?
給你一個數組,數組裏只有兩個數是出現一次的,其他數字都是出現兩次,要求用O(n)時間複雜度,O(1)空間複雜度的算法找出這兩個數
要是按以前我acm的做法,直接就是map存次數,又因爲map自動有序,所以輸出map[0]和map[1]就行了,but it can‘t let 空間複雜度保證O(1),
通過這題學到了一種巧妙的利用位運算解題的思路。
衆所周知,x ^ x = 0,所以先用異或遍歷一遍數組,設要輸出的兩個數一個爲x,一個爲y,那麼遍歷之後得到的結果爲x^y,因爲這x,y兩個數不同,所以必定會
有起碼有一位在各自的對應位上不同,又因爲是異或,所以x^y中爲1的位就是x和y中對應位不同的位置。設ans = x ^ y,利用ans&(-ans)求出最低爲1
的位是哪一位,至於爲什麼ans&(-ans)可以求出來,不會的可以去學一下樹狀數組(甩鍋= =+),如果實在理解不了的,就用while循環求吧。求出這個最低位
之後,我們就可以根據數組中的元素在這一位是1還是0來把他們分爲兩組,這樣就可以保證x,y被分開,然後對這兩組分別進行異或求結果。這題是
Special judge,return 的數組中的元素不要求保證順序。
public class Solution {
    public int[] singleNumber(int[] nums) {
        int ans = 0;
        int a[] = new int [2];
        int index = 1;
        int len = nums.length;
        for(int i=0;i<len;i++){
            ans ^= nums[i];
        }
        index = ans & (-ans);
        for(int i=0;i<len;i++){
            if((nums[i] & index) == 0)
                a[0] ^= nums[i];
            else
                a[1] ^= nums[i];
        }
        return a;
    }
}


發佈了244 篇原創文章 · 獲贊 18 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章