1. 程式人生 > >LeetCode 137. Single Number II

LeetCode 137. Single Number II

without 當前 with 結果 example println ould 等於 記錄

分析

參考https://cloud.tencent.com/developer/article/1131945

我們想要達到的效果其實是——
           a b
初始狀態     : 0 0
第一次碰見某個數x: 0 x(把x記錄在b中)
第二次碰見某個數x: x 0(把x記錄在a中)
第三次碰見某個數x: 0 0(把a和b都清空,可以處理其他數)
還記得我們之前處理“所有元素都出現兩次,只有一個特殊元素出現一次”的問題嗎?其實我們那會想要達到的狀態也是——
           a
初始狀態     : 0
第一次碰見某個數x: x(把x記錄在a中)
第二次碰見某個數x: 0(把a清空)
然後我們剛好就找到了異或運算可以處理這個問題。
那麽這次我們同樣利用異或運算,看能不能設計出一種變換的方法讓a和b按照上述變換規則,進行轉換。
b=0時碰到x,就變成x;b=x時再碰到x,就變成0,這個不就是異或嗎?所以我們也許可以設計b=b xor x。
但是當b=0時再再碰到x,這時候b還是要為0,但這時候不同的是a=x,而前兩種情況都是a=0。所以我們可以設計成:b=(b xor x)&~a
同樣道理,我們可以設計出:a=(a xor x)&~b
在這種變換規則下,a和b都能按照我們設定的狀態來發生轉化。最後那個只出現一次的元素必定存儲在b中。


難度 中

來源

https://leetcode.com/problems/single-number-ii/

題目

Given a non-empty array of integers, every element appears three times except for one, which appears exactly once. Find that single one.

Note:

Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?

Example 1:

Input: [2,2,3,2]

Output: 3

Example 2:

Input: [0,1,0,1,0,1,99]

Output: 99

解答

 1 package LeetCode;
 2 
 3 //位操作
 4 public class L137_SingleNumberII {
 5     /*public int singleNumber(int[] nums) {
 6         int result=0;
 7         for(int i=0;i<32;i++)//逐位對result進行設置
 8         {
 9             int sum=0;
10 for(int j=0;j<nums.length;j++){ 11 //如果這些數字的當前位為1,就用sum記錄當前位為1的數目 12 //如果是1向左平移i位,求且的結果就不等於1了 13 sum+=(nums[j]>>i) &1; 14 } 15 result|=(sum%3)<<i; 16 } 17 return result; 18 }*/ 19 public int singleNumber(int[] nums) { 20 int a =0; 21 int b =0; 22 for(int i=0;i<nums.length;i++){ 23 b = b ^ nums[i] & ~a; 24 a = a ^ nums[i] & ~b; 25 } 26 return a|b; 27 } 28 public static void main(String[] args){ 29 L137_SingleNumberII l137=new L137_SingleNumberII(); 30 int[] nums={0,1,0,1,0,1,99}; 31 System.out.println(l137.singleNumber(nums)); 32 } 33 }

LeetCode 137. Single Number II