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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

位运算的那些奇技淫巧 | 掌(装)握(逼)必备,妙解两道算法题

發布時間:2025/3/20 编程问答 17 豆豆
生活随笔 收集整理的這篇文章主要介紹了 位运算的那些奇技淫巧 | 掌(装)握(逼)必备,妙解两道算法题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

這里寫目錄標題

        • 一、常(裝)見(逼)的位操作
          • 先看幾個有意思的位操作:
          • 1、判斷奇數偶數
          • 2、交換兩個數字
          • 3、找出沒有重復的數字
          • 4、m的n次方
          • 5、判斷一個數是不是二的指數
          • 6、找出不大于N的最大2的冪指數
        • 二、leetcode解題
          • 136.只出現一次的數字(簡單)
          • 191.位1的個數(簡單)

看完本文,可以順便解決leetcode以下兩個題目:
136.只出現一次的數字(簡單)
191.位1的個數(簡單)

一、常(裝)見(逼)的位操作

先看幾個有意思的位操作:

或操作 | 和空格將英文字符轉換為小寫,小寫本身還是小寫

(‘a’ | ’ ') = ‘a’
(‘A’ | ’ ') = ‘a’

與操作 & 和下劃線將英文字符轉換為大寫,大寫本身還是大寫

(‘b’ & ‘’) = ‘B’
(‘B’ & '’) = ‘B’

n&(n-1) 消除數字 n 的二進制表示中的最后一個 1

異或^和空格進行英文字符大小寫互換;判斷異號

(‘d’ ^ ’ ') = ‘D’
(‘D’ ^ ’ ') = ‘d’
x^y < 0;異號,否則同號

下面我們從簡單開始,一步一步的實現復雜的位運算~

1、判斷奇數偶數

看到這個,你肯定覺得很簡單,然后隨手寫下:

if (n % 2 == 0) { // 偶數 } else { // 奇數 }

其實使用位運算,可以這樣寫

if ( n & 1 == 1) {// 奇數 } else {// 偶數 }

因為如果一個二進制表示偶數的話

偶數的最后一位肯定是0;

奇數的最后一位肯定是1;

2、交換兩個數字

這個也是很常見的操作,很簡單的就可以寫下來:

temp = x; x = y; y = temp;

但是如果在實際工作中,遇到不借助輔助空間,依舊讓你去交換兩個數字呢?
這個時候,位運算的優勢就體現出來了
位運算實現如下:

x = x^y y = x^y x = x^y

看的第一眼,肯定很懵~ 啥玩意兒這是

首先,我們需要知道兩個個基礎的公式:

n^n =0; 即相同的兩個數異或結果是0
n^0 = n;一個數和0異或的結果是本身

所以,上面展開一下,就是

x = x^y y = x^y^y = x^0 = x x = x^y = x^y^x = x^x^y = 0^y = y
3、找出沒有重復的數字

我們以上面的為基礎,即相同的兩個數異或結果是0;一個數和0異或的結果是本身
那我們就把這一些數字,遍歷一遍,全部異或一下,不就OK了?

4、m的n次方

要求一個數m的n次方,但是不能使用POW函數,如何做?
不要使用 m x m x m x m x m~ 一直乘以n次,太low了;
時間復雜度就是 O(n)

使用階乘,復雜度可以降低到O(log N)

int pow(int n){int sum = 1;int tmp = m;while(n != 0){if(n & 1 == 1){sum *= tmp;}tmp *= tmp;n = n >> 1;}return sum; }

上述代碼要是不理解二進制可能你就看不懂,這里我來舉例解釋一下

比如,求m的 5次方
我們把5用二進制表示,就是 0101,
從右往左看,第一個1 代表一個m
第二個1代表一個m x m x m x m ;
當二進制的這一位有1的時候,才把該位置代表的累乘的數算上,否則不算,繼續看下一位的情況;

5、判斷一個數是不是二的指數

如果一個數,是二的指數,那么它的二進制表示,肯定只有一個1
結合上面說到的:n&(n-1) 消除數字 n 的二進制表示中的最后一個 1

問題就好解決了

return (n > 0 ) && (n & (n - 1) == 0) ) ;
6、找出不大于N的最大2的冪指數

假設這個數是 19;
19用二進制表示就是 00010011
我們需要的結果就是 16 ;00010000
也就是 把 0010011,只保留最左邊的一個1;
這個思路很簡單,就是把最左邊的1后面位,全部變成1;然后整體加1;由于加1之后會進位,所以在整體右移一位


應該怎么最左邊的1后面位,全部變成1呢?

n |= n >> 1;
n |= n >> 2;
n |= n >> 4;

n |= n >> 1;
結果是最左邊的1和其右邊,也會有一個1;11

n |= n >> 2;
結果是最左邊的11和其右邊,也會有一個11;1111

n |= n >> 4;
結果是最左邊的1111和其右邊,也會有一個11;11111111

如此這樣,后面就都變成1了,然后+1,右移一位就行

二、leetcode解題

136.只出現一次的數字(簡單)

這個題剛剛上面說過了,全部都異或
直接上答案;

class Solution { public:int singleNumber(vector<int>& nums) {//異或int n=nums.size();int res=0;for(int i=0;i<n;i++){res^=nums[i];}return res;} };
191.位1的個數(簡單)


思路:
只需要記得:
n&(n-1) 消除數字 n 的二進制表示中的最后一個 1

class Solution { public:int hammingWeight(uint32_t n) {int res = 0;while (n != 0) {n = n & (n - 1);res++;} return res;} };

總結

以上是生活随笔為你收集整理的位运算的那些奇技淫巧 | 掌(装)握(逼)必备,妙解两道算法题的全部內容,希望文章能夠幫你解決所遇到的問題。

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