leetcode260. Single Number III

先說第一種題

題目:

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?

我的解法:對數組排序,兩個兩個跳着比較直到找到不等的,時間複雜度O(NlogN)

class Solution {
public:
    int singleNumber(vector<int>& nums) 
    {
        sort(nums.begin(),nums.end());
        int size = nums.size();
        if (size == 1)
            return nums[0];
            
        for (int i = 1; i < size; i += 2)
            if (nums[i] != nums[i - 1])
                return nums[i - 1];
                
        
        return nums[size -1];
    }
};

參考其他解法,知道了這類題考察的是位運算

AC解:

class Solution {
public:
    int singleNumber(vector<int>& nums) 
    {
        int x = 0;
        int size = nums.size();
        for (int i = 0; i < size; i++)
            x ^= nums[i];
        return x;
    }
};
或者直接 return accumulate(nums.begin(),nums.end(),0,bit_xor<int>());

升級版題目:

Given an 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?

用一個數組來存儲所有元素每個位上1的個數,模3剩下的就是所有元素此位上的數字

class Solution {
public:
    int singleNumber(vector<int>& nums) 
    {
        const int length = sizeof(int) * 8;
        int count[length];
        fill(count,count + length,0);
        int size = nums.size();
        
        for (int i = 0 ; i < size; i++)
            for (int j = 0; j < length; j++)
            {
                count[j] += (nums[i] >> j) & 0x1;
                count[j] %= 3;
            }
        
        int result = 0;
        for (int i = 0; i < length; i++)
            result += (count[i] << i);
        
        return result;
    }
};

再次升級版:

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].

AC解: 解法分兩步,精妙之處在於diff

1.對所有數字進行異或運算,diff的值爲要求的兩個數進行異或運算的結果,再diff &= -diff,得到的結果爲diff中從右到左第一個位爲1的的數,例如0x1010 其負數爲0x0110,與運算的結果爲0x0010。並且可以知道這兩個數的此位必定一個爲0一個爲1

2.根據此位是否爲1將數分爲了兩部分,分別對兩部分進行異或運算,因爲相同的兩個數異或操作後結果爲0,所以兩組數的最終結果就是所要求得的數

class Solution {
public:
    vector<int> singleNumber(vector<int>& nums) 
    {
        //數組中所有位進行異或,diff爲所求的兩個數異或的結果
        int diff = accumulate(nums.begin(),nums.end(),0,bit_xor<int>());
        //取得從右到左第一個爲1的位,並且這兩個數的此位一定不同
        diff &= -diff;
        
        vector<int> ans(2,0);
        //分離兩個數
        for (auto a : nums)
            if (a & diff)//當前元素的此位爲1
                ans[0] ^= a;        //不算這兩個數,當前位爲0或1的數肯定是成對出現的
            else                    //相同的數異或操作後爲0
                ans[1] ^= a;
        
        return ans;
    }
};




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