日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

每天一道LeetCode-----一个整数序列,每个元素出现两次,只有一个(两个)出现一次,找到这个(这两个)元素

發布時間:2024/4/19 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 每天一道LeetCode-----一个整数序列,每个元素出现两次,只有一个(两个)出现一次,找到这个(这两个)元素 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Single Number

原題鏈接Single Number

一個整數序列,每個數字都出現兩次只有一次數字出現了一次,找到只出現一次的那個數字

位運算的異或算法有如下幾個性質

  • 值相同的兩個數字異或結果為0,即a ^ a = 0
  • 交換律,即a ^ b = b ^ a
  • 綜上兩條性質,得到a ^ b ^ b = b ^ a ^ b = b ^ b ^ a = a

所以只需要遍歷一遍序列,并做異或運算,所有出現兩次的數字在異或的過程中都變為0,只留下唯一的一個出現一次的數字

代碼如下

class Solution { public:int singleNumber(vector<int>& nums) {return std::accumulate(nums.begin(), nums.end(), 0, bit_xor<int>()); } };

Single Number II

原題鏈接Single Number II

一個整數序列,每個數字都出現三次只有一個數字出現了一次(也可以出現一次或兩次),找到這個數字

利用上面異或的思想,找到某種運算使得三次計算結果后為0,一次和兩次的計算結果和數字本身相同,本質上還是采用bitmap的思想

采用兩個整數變量a和b,如果a的某一位是1,代表目前為止這一位出現了1次,如果b的某一位是1,代表到目前為止這一位出現了2次,a和b對應位置上都為0表示這一位出現了0次或3次(因為需要保證三次運算結果為0)

僅僅觀察一位的話,有如下的轉換關系,其中c是當前遍歷到的數字的對應位,a’和b’是更新后的a和b

abca’b’
00000
00110
10010
10101
01001
01100

找到a’和b’的運算式子,即將a’為1和b’為1的情況分離出來

abca’
0011
1001
abcb’
1011
0101

得到運算式

a' = ((~a) & (~b) & c) | (a & (~b) & (~c)); b' = (a & (~b) & c) | ((~a) & b & (~c));

最后,a’表示出現一次的數字,b’表示出現兩次的數字

代碼如下

class Solution { public:int singleNumber(vector<int>& nums) {int a = 0, b = 0;for(auto& c : nums){int tmpa = ((~a) & (~b) & c) | (a & (~b) & (~c));int tmpb = (a & (~b) & c) | ((~a) & b & (~c));a = tmpa;b = tmpb;}return a | b;} };

Single Number III

原題鏈接Single Number III

一個整數序列,每個數字都出現了兩次只有兩個數字出現了一次,找到這兩個數字

兩個出現一次的數字不能簡單的使用異或找到,但是考慮一下,假設a, b分別是這兩個只出現一次的數字,c1, c2, …, cn代表其他的數字,那么

a, c1, c2, …, cn這個序列可以采用問題一的解法求得a(異或一遍)

b, c1, c2, …, cn這個序列同樣可以采用問題一的解法

但是要怎樣分離出a和b呢,如果最開始異或一遍整數序列,那么得到的結果就是a ^ b的值,由于a和b肯定不相等,那么a ^ b != 0,這就會導致結果中肯定有一位是1,哪一位都可以,不過最好找的是最右邊的1,即

int diff = a ^ b; diff = (diff) & (~(diff - 1));

此時diff只有一位是1,且這一位的1是整個diff中最右邊的1。那么就可以采用這個diff區分a和b,因為a和b一定有一個該位是1,有一個該位是0,才可以在異或結果中使得該位是1

剩下的工作仍然是異或一遍序列即可,代碼如下

class Solution { public:vector<int> singleNumber(vector<int>& nums) {vector<int> res{0, 0};int diff = std::accumulate(nums.begin(), nums.end(), 0, bit_xor<int>());diff = (diff) & (~(diff - 1));for(auto& num : nums){/* 這里無需考慮其他數字與diff的異或結果,因為他們都是成對出現的,異或不異或都無所謂 */if(diff ^ num == 0){res[0] ^= num;}else{res[1] ^= nums;}}return res;} };

這三道題主要考察的是對位運算的掌握,尤其是位操作,本質上是bitmap思想,用每一位表示出現的情況

與50位技術專家面對面20年技術見證,附贈技術全景圖

總結

以上是生活随笔為你收集整理的每天一道LeetCode-----一个整数序列,每个元素出现两次,只有一个(两个)出现一次,找到这个(这两个)元素的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。