《位運算技巧以及Leetcode的一些位運算題目》

目錄

  • 技巧
  • 練習位運算
        • [461. 漢明距離](https://leetcode-cn.com/problems/hamming-distance/)
        • [190. 顛倒二進制位](https://leetcode-cn.com/problems/reverse-bits/)
        • [136. 只出現一次的數字](https://leetcode-cn.com/problems/single-number/)
        • [260. 只出現一次的數字 III](https://leetcode-cn.com/problems/single-number-iii/)
        • [268. 丟失的數字](https://leetcode-cn.com/problems/missing-number/)
        • [693. 交替位二進制數](https://leetcode-cn.com/problems/binary-number-with-alternating-bits/)
        • [476. 數字的補數](https://leetcode-cn.com/problems/number-complement/)
  • 練習二進制思想
        • [342. 4的冪](https://leetcode-cn.com/problems/power-of-four/)
        • [318. 最大單詞長度乘積](https://leetcode-cn.com/problems/maximum-product-of-word-lengths/)
        • [338. 比特位計數](https://leetcode-cn.com/problems/counting-bits/)
  • 一些補充
        • 劍指 Offer 56 - I. 數組中數字出現的次數

技巧

位運算的一些基礎技巧

 x ^ 0... = xx ^ 1... = ~xx ^ x = 0x & 0... = 0x & 1... = xx & x = xx | 0... = xx | 1... = 1...x | x = x

進階技巧

n & (n-1) 可以去除n的位級表示中最低的一位:
如 n = 11110100 , n - 1 = 11110011
n & (n-1) = 11110000
n & (-n)  可以得到n的位級表示中最低的那一位:
如 n = 11110100 , 取負:-n = 00001100
n & (-n) = 00000100

練習位運算

461. 漢明距離

先異或運算,然后統計1個數:

class Solution {
public:int hammingDistance(int x, int y) {int XOR_result = x ^ y;int result = 0;while(XOR_result != 0){result += (XOR_result & 1);XOR_result = XOR_result >> 1;}return result;}
};

190. 顛倒二進制位

result不斷左移,最低位加上n的最低位,n不斷右移。

class Solution {
public:uint32_t reverseBits(uint32_t n) {uint32_t result = 0;for(int i = 0; i < 32; i++){result = result << 1;result += n & 1;n = n >> 1;}return result;}
};

136. 只出現一次的數字

思路一:哈希先掃一遍,然后再掃一遍,找到second為1的it。

class Solution {
public:int singleNumber(vector<int>& nums) {unordered_map<int,int> umap;int result = 0;for(int i = 0; i < nums.size(); i++){umap[nums[i]]++;}for(auto it : umap){if(it.second == 1) return it.first;}return 0;}
};

思路二:利用 x ∧ x = 0 和 x ∧ 0 = x 的特點,將數組內所有的數字進行按位異或。出現兩次
的所有數字按位異或的結果是 0,0 與出現一次的數字異或可以得到這個數字本身。神仙思路!

class Solution {
public:int singleNumber(vector<int>& nums) {int result = 0;for(int num : nums)result = num ^ result;return result;}
};

260. 只出現一次的數字 III

這次是有兩個不同的元素,那么用位運算如何做呢?
覺得這個題解寫的很好,淺顯易懂。
某題解
編程時注意一下細節:
1、&的優先級比==低,所以需要加括號
2、用int作為res會報錯,需要用long

class Solution {
public:vector<int> singleNumber(vector<int>& nums) {long res = 0;for(int i = 0; i < nums.size(); i++){res = res ^ nums[i];}//此時res = a ^ b;//找出1的位級表示中最低的那一位,代表著a與b在這一位是不一樣的,假設a在這一位為0,b在這一位為0res = res & (-res);int a = 0;int b = 0;for(int i = 0; i < nums.size(); i++){if((nums[i] & res) == 0)  //不可能b,而且除了a其他符合要求的都是重復的a = nums[i] ^ a;else b = nums[i] ^ b;}return {a,b};}
};

268. 丟失的數字

XOR原理:x ^ x = 0; 0 ^ y =y;
兩個相同的數字XOR之后為0,如果這個數字只出現了一次,那么XOR之后還是本身。這一題本質上和上一題是一樣的。
一些細節,看注釋

class Solution {
public:int missingNumber(vector<int>& nums) {int n = nums.size();int result = n;             //因為for循環中i不能為n,而我們必須遍歷[0,n],所以初值設置為nfor(int i = 0; i < n; i++)  //遍歷nums數組,其丟失數在nums[] + [0..n]中只出現了一次{result = result ^ i ^ nums[i];}return result;}
};

693. 交替位二進制數

class Solution {
public:bool hasAlternatingBits(int n) {int prev_tail = n & 1;while(n){int now_tail = (n >> 1) & 1;if(now_tail == prev_tail) return false;prev_tail = now_tail;n = n >> 1;}return true;}
};

476. 數字的補數

思路一:一個一個來,注意倒序。

class Solution {
public:int findComplement(int n) {int result = 0;vector<int> res;while(n){res.emplace_back(!(n & 1));n = n >> 1;}for(int i = res.size() - 1; i >=0; i--){result = (result << 1) | res[i];}return result;}
};

當然也可以使用棧來做,思路一樣的:

class Solution {
public:int findComplement(int n) {int result = 0;stack<int> res;while(n){res.push(!(n&1));n >>= 1;}while(!res.empty()){result = (result << 1) | res.top();res.pop();}return result;}
};

思路二:使用異或
舉例:
5的二進制是:0101,7的二進制是: 0111,它們的抑或為:0010,去掉前導零位即為取反。
再來一個例子,假設a為1110 0101,b為1111 1111,a^b = 0001 1010是a的取反。也就是說二進制位數與num相同,且全為1的數tmp與num的抑或即為所求。

class Solution {
public:int findComplement(int n) {int tmp=0;int tmp_n = n;while(n){tmp = (tmp << 1) | 1;n >>= 1;}return tmp ^ tmp_n;}
};

練習二進制思想

342. 4的冪

先考慮2的次方:
如果n為2的整數次方,那么它的二進制一定是0...1...0的形式;那么n-1的二進制應該是0..011...1的形勢。這兩個數按位求與的結果一定為0。
如果n為4的整數次方,它一定為2的偶數冪。所以4的冪與二進制數(1010101010…10)相與會得到0.
int 為32位,每4位1010對應16進制a,所以應該為0xaaaaaaaa;
注意&與==的優先級。

class Solution {
public:bool isPowerOfFour(int n) {return ( n > 0 && (n & n-1) == 0 && (n & 0xaaaaaaaa) == 0);}
};

318. 最大單詞長度乘積

怎樣快速判斷兩個字母串是否含有重復數字呢?可以為每個字母串建立一個長度為26的二進制數字,每個位置表示是否存在該字母。如果兩個字母串含有重復數字,那它們的二進制表示的按位與不為0。同時,我們可以建立一個哈希表來存儲字母串(在數組的位置)到二進制數字的映射關系,方便查找調用。

class Solution {
public:int maxProduct(vector<string>& words) {unordered_map<int,int> hashmap;             //使用哈希表來存儲(位掩碼 -> 單詞長度)int ans = 0;for(auto word : words)                      //遍歷每個string{int mask = 0;                           //位掩碼int size = word.size();                 //單詞長度for(auto c : word)                      //encode位掩碼mask = mask | (1 << (c-'a'));hashmap[mask] = max(hashmap[mask],size);//如果掩碼相同,存儲更長的字符串(說明有些字符重復)//對比當前單詞與之前的所有單詞,無重復字符,且長度乘積大于ans則更新ansfor(auto it : hashmap){if((mask & it.first)== 0)            //如果無重復字符{ans = max(ans,size*it.second);}}}return ans;}
};

338. 比特位計數

利用dp+位運算。
定義一個數組dp,dp[i]表示數字i的二進制含有1的個數。
對于第i個數字,如果它二進制的最后一位為1,那么它含有1的個數則為dp[i] = dp[i-1]+1;
如果它二進制的最后一位為0,那么它含有1的個數和其右移結果相同,即dp[i] = dp[i>>1]

class Solution {
public:vector<int> countBits(int num) {vector<int> dp(num+1,0);for(int i = 1; i <= num; i++){if((i & 1) == 1)dp[i] = dp[i-1] + 1;else dp[i] = dp[i>>1];}return dp;}
};

一些補充

2021.7.4

劍指 Offer 56 - I. 數組中數字出現的次數

一個整型數組 nums 里除兩個數字之外,其他數字都出現了兩次。請寫程序找出這兩個只出現一次的數字。要求時間復雜度是O(n),空間復雜度是O(1)。

示例 1:
輸入:nums = [4,1,4,6]
輸出:[1,6][6,1]
示例 2:
輸入:nums = [1,2,10,4,1,4,3,3]
輸出:[2,10][10,2]
限制:
2 <= nums.length <= 10000

兩個只出現依次的數字位x,y
x和y二進制至少有一位不同,根據此位可以將nums劃分成分別包含x和y的兩個子數組。
分別對兩個子數組遍歷執行異或操作,可以得到兩個只出現一次的數字x,y。
1、遍歷nums數組執行異或,得到結果 x^y
2、x^y某二進制位為1,則x和y的此二進制位一定不同。
初始化一個輔助變量m = 1,從右向左循環判斷,可以得到x^y的首位1,記錄在m中。
3、拆分nums為兩個子數組
4、分別遍歷兩個子數組執行異或
for(num : nums)
if(num & m == 1) x ^= num;
else y ^= num;
return x,y;
最終代碼:

vector<int> singleNumbers(vector<int>& nums)
{int ret = 0;for(int n : nums)ret ^= n;			// x^yint div = 1;while((ret & div) == 0)div <= 1;int x = 0, y = 0;for(int n : nums){if(div & n == 0)a ^= n;else b ^= n;}return vector<int> {x,y};
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/377080.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/377080.shtml
英文地址,請注明出處:http://en.pswp.cn/news/377080.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

linux讀取配置文件(C語言版)

一個通用的linux系統中C語言版讀取配置文件的函數。 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h> #include <errno.h>#define KEYVALLEN 100/* 刪除左邊的空格 */ char * l_trim(char * szOutput, con…

java 范圍搜尋要怎么弄_搜索范圍

java 范圍搜尋要怎么弄Problem statement: 問題陳述&#xff1a; Given an array of integers nums sorted in ascending order, find the starting and ending position of a given target value. 給定一個以升序排列的整數nums數組&#xff0c;請找到給定目標值的開始和結束…

boa + ajax + cgi ajax請求cgi

最近公司要做一個通訊管理機,然后需要和另外一個同事一起做,我們需要用到boaAjaxCGI,以前沒試過與CGI交互,一開始發現問題挺大的,用ajax請求cgi,總是不返回數據,又或者請求回來的是cgi的源碼,后來發現,通過本地IIS或者直接打開html頁面請求的,返回來的都是cgi的源碼或者返回失敗…

《DBNotes:single_table訪問方法、MRR多范圍讀取優化、索引合并》

目錄single_table訪問方法constrefref_or_nullrangeindexallMRR多范圍讀取優化索引合并intersectionunionsort-unionsingle_table訪問方法 const 在主鍵列或者unique二級索引與一個常數進行等值比較時才有效。 如果主鍵或者unique二級索引的索引列由多個列構成&#xff0c;則…

怎樣通過命令管理Windows7桌面防火墻

&#xff08;1&#xff09;啟用桌面防火墻netsh advfirewall set allprofiles state on&#xff08;2&#xff09;設置默認輸入和輸出策略netsh advfirewall set allprofiles firewallpolicy allowinbound,allowoutbound以上是設置為允許&#xff0c;如果設置為拒絕使用blockin…

ruby推送示例_Ruby for循環示例

ruby推送示例for循環 (The for loop) In programming, for loop is a kind of iteration statement which allows the block to be iterated repeatedly as long as the specified condition is not met or a specific number of times that the programmer knows beforehand. …

《DBNotes: Buffer Pool對于緩沖頁的鏈表式管理》

目錄Buffer Pool回顧Buffer Pool內部組成freelistflushlistLRU鏈表管理以及改進Buffer Pool回顧 我們知道針對數據庫的增刪改刪操作都是在Buffer Pool中完成的&#xff0c;一條sql的執行步驟可以認為是這樣的&#xff1a; 1、innodb存儲引擎首先在緩沖池中查詢有沒有對應的數據…

一個延時調用問題

如果用下面第1行的寫法&#xff0c;調用 [NSObject cancelPreviousPerformRequestsWithTarget:self selector:selector(removeFromSuperview) object:nil]; 可以生效 如果用下面第3行的寫法&#xff0c;調用 [NSObject cancelPreviousPerformRequestsWithTarget:self selector:…

onclicklistener 方法使用匯總

相信很多像我一樣的新手學習ANDROID開發會遇到這個問題&#xff0c;通過這幾天的歸類和總結&#xff0c;將我的理解寫在下面&#xff0c;歡迎大家一起前來討論&#xff1a; 以按鈕BUTTON的監聽事件為例&#xff0c;以下的監聽實現都是等價的&#xff1a; 1.使用接口繼承按鈕監聽…

《源碼分析轉載收藏向—數據庫內核月報》

月報原地址&#xff1a; 數據庫內核月報 現在記錄一下&#xff0c;我可能需要參考的幾篇文章吧&#xff0c;不然以后還得找&#xff1a; MySQL 代碼閱讀 MYSQL開源軟件源碼閱讀小技巧 MySQL 源碼分析 聚合函數&#xff08;Aggregate Function&#xff09;的實現過程 MySQL …

vim中的jk為什么是上下_JK的完整形式是什么?

vim中的jk為什么是上下JK&#xff1a;開玩笑 (JK: Just Kidding) JK is an abbreviation of "Just Kidding". JK是“ Just Kidding”的縮寫 。 It is an expression, which is commonly used in messaging or chatting on social media networking sites like Faceb…

百度歸來的學長做報告

今天下午下課到現在才總算閑下來&#xff0c;本來計劃這個時間應該是讀英語&#xff0c;做英語模擬題的時間&#xff0c;但是&#xff0c;我不得不寫點什么來記錄下剛才的事——在百度實習并且簽下工作的學長做報告。 原本認為每個人的成功&#xff08;請允許我目前的眼光簽個好…

轉:Google論文之三----MapReduce

文章來自于&#xff1a;http://www.cnblogs.com/geekma/p/3139823.html MapReduce&#xff1a;大型集群上的簡單數據處理 摘要 MapReduce是一個設計模型&#xff0c;也是一個處理和產生海量數據的一個相關實現。用戶指定一個用于處理一個鍵值&#xff08;key-value&#xff09;…

合約 cd 模式_CD的完整形式是什么?

合約 cd 模式CD&#xff1a;光盤 (CD: Compact Disc) CD is an abbreviation of "Compact Disc". CD是“ Compact Disc”的縮寫 。 It is a digital optical disc originally developed to store the audio of recordings in the format of a data file used as a p…

《DBNotes:Join算法的前世今生》

目錄NestLoopJoin算法Simple Nested-Loop JoinIndex Nested-Loop JoinBlock Nested-Loop JoinBatched Key AccessHash Join算法In-Memory Join(CHJ)On-Disk Hash Join參考鏈接在8.0.18之前&#xff0c;MySQL只支持NestLoopJoin算法&#xff0c;最簡單的就是Simple NestLoop Joi…

如何解決迅雷插件導致IE10崩潰的問題

Windows 8里面帶的IE10酷不酷&#xff1f;沉浸式界面果然不同凡響&#xff0c;IE10讓人幾乎認不出來了&#xff01;這是微軟的瀏覽器么&#xff1f;上面這張圖是Windows8下Metro UI的新界面IE10&#xff0c;不過當我們切換回傳統桌面的時候&#xff0c;也有IE10的經典版的。好吧…

UNITY3D與iOS交互解決方案

原地址&#xff1a;http://bbs.18183.com/thread-456979-1-1.html 本帖最后由 啊,將進酒 于 2014-2-27 11:17 編輯 “授人以魚&#xff0c;不如授人以漁”&#xff0c;以UNITY3D調用iOS版的91SDK為例&#xff0c;利用C# / C / OBJ-C交互原理,本文將詳細介紹UNITY3D與iOS之間交互…

c:if equal_C ++中的std :: equal()

c:if equalequal()作為STL函數 (equal() as a STL function) Syntax: 句法&#xff1a; bool equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2);Where, 哪里&#xff0c; InputIterator1 first iterator to start of the first sequence range I…

《DBNotes:Buffer Pool刷臟頁細節以及改進》

本筆記知識沿用之前DBNotes: Buffer Pool對于緩沖頁的鏈表式管理的部分知識 目錄獲取一個空閑頁的源碼邏輯Page_Cleaner_ThreadLRU_Manager_ThreadHazard Pointer作為驅逐算法改進參考獲取一個空閑頁的源碼邏輯 任何一個讀寫請求都需要從Buffer pool來獲取所需頁面。如果需要的…

WordPress刪除數據中標題重復文章的方法

一種是刪除重復的方法是&#xff1a;使用插件,大家可以去官網上下載 二種刪除重復的方法是&#xff1a;登錄數據庫&#xff0c;使用sql語句刪除&#xff0c;具體的語句為如下代碼&#xff1a; CREATE TABLE my_tmp AS SELECT MIN(ID) AS col1 FROM wp_posts GROUP BY post_titl…