[LeetCode] Single Number


Given an array of integers, every element appears twice except for one. Find that single one.

Note:

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

 

感謝cnblog博主feiling,這篇博客一方面參考了feiling的博客,也加入了自己的一些看法。

[解題思路]

要求線性時間復雜度,同時空間復雜度為O(1),即只允許開常數個空間。

最直接的思路是對每一個元素嘗試查找是否有重,如果沒有重,就返回。

class Solution {
public:
    int singleNumber(int A[], int n) {
        // IMPORTANT: Please reset any member data you declared, as
        // the same Solution instance will be reused for each test case.
        int i = 0, j = 0;
        int ans = 0;
        for(i = 0;i < n;i++)
        {
            for(j = 0;j < n;j++)
            {
                if(i == j)
                    continue;
                else if(A[i] == A[j])
                    break;
                    else continue;
            }
            
            if(j == n)
                return A[i];
        }
    }
};

不幸的是雖然是o(n2)的時間復雜度,但是還是超時了。於是乎就得想一個o(n)的算法。

o(n)的算法只能是線性掃描一遍,可能的相法是位運算。對於異或來說:

1. 異或運算是可交換,即 a ^ b = b ^ a

2. 0 ^ a = a

那么如果對所有元素做異或運算,其結果為那個出現一次的元素,理解是a1 ^ a2 ^ ....,可以將所有相同元素交換至相鄰位置,首先運算相同元素,則會產生(n - 1)/2個0異或積,剩余一個單一元素,他們的異或積為這個單一元素自己,得解。

復制代碼
 1 public class Solution {
 2     public int singleNumber(int[] A) {
 3         // Note: The Solution object is instantiated only once and is reused by each test case.
 4         if(A == null || A.length == 0){
 5             return 0;
 6         }
 7         int result = A[0];
 8         
 9         for(int i = 1; i < A.length; i++){
10             result = result ^ A[i];
11         }
12         return result;
13     }
14 }
復制代碼

本題擴展

1.一個數組中有兩個元素只出現一次,其他所有元素都出現兩次,求這兩個只出現一次的元素

[解題思路]

將數組所有元素都進行異或得到一個不為0的結果,根據這個結果中的不為0的某一位將數組分成兩組

將兩組中的元素進行異或,如兩個數組的異或值都不為0,則得到最后結果

 

2.一個數組中有一個元素只出現1次,其他所有元素都出現k次,求這個只出現1次的元素

[解題思路]

當k為偶數時,同lss

當k為奇數時,將數組中每個元素的每一位相加mod k,得到結果即位出現1次的元素,時間復雜度O(nlen),空間復雜度為O(1)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM