算法02 二進制與位運算

二進制作為計算機底層數據的核心表示方式,其獨特的位結構和運算規則在算法設計中有著廣泛且關鍵的應用。以下從基礎操作、算法技巧、數據結構、經典問題等多個維度,全面梳理二進制在算法中的應用:


?
一、基礎位運算:算法的“原子操作”


?
二進制的核心優勢在于位運算的高效性(時間復雜度通常為O(1)),常見位運算包括:
?
與(&):兩個位都為1則為1,否則為0。常用于“保留指定位”(如?x & mask?保留mask中1對應的位)。
?
或(|):兩個位有一個為1則為1,常用于“設置指定位為1”(如?x | mask?將mask中1對應的位設為1)。
?
異或(^):兩個位不同則為1,相同則為0。特性:?x ^ x = 0?,?x ^ 0 = x?,可用于“交換變量”“找唯一出現奇數次的數”等。
?
左移(<<)
:?x << k??等價于 ?x * 2^k?(無溢出時),快速放大。
?
右移(>>):?x >> k??等價于 ?x /2^k?(整數除法),快速縮小。
?
取反(~):位反轉(0變1,1變0),常用于構造掩碼(如?~0?是全1的二進制)。
?
這些操作是二進制應用的基礎,幾乎所有二進制相關算法都依賴它們。


?
二、狀態壓縮:用二進制表示“集合狀態”


?
當問題需要表示“元素是否被選擇”“狀態是否激活”等集合信息時,二進制可將集合狀態壓縮為一個整數,大幅節省空間并簡化操作。
?
典型場景:
?
1.?子集枚舉
若有?n?個元素,每個子集可表示為一個?n?位二進制數(第?i?位為1表示元素?i?在子集中)。例如,?n=3?時,二進制?101?表示子集?{0, 2}?。
枚舉所有子集的代碼可簡化為:
python
? ?

for mask in range(0, 1 << n): ?# 1<<n 即2^n,覆蓋所有子集
? ? # mask的二進制表示即為一個子集
?
?
2.?動態規劃中的狀態壓縮
例如旅行商問題(TSP):用?dp[mask][u]?表示“已訪問的城市集合為?mask?(二進制),當前在城市?u?時的最小距離”。其中?mask?的第?i?位為1表示城市?i?已訪問。
狀態轉移依賴位運算:?if not (mask & (1 << v))?(判斷城市?v?是否未訪問)。
?
3.?位掩碼優化
例如“N皇后問題”中,用三個整數(列、主對角線、副對角線)的二進制表示當前禁止放置的位置,通過位運算快速判斷合法性。


?
三、二進制特性:解決數學與計數問題


?
二進制的表示本身蘊含特殊規律,可用于優化數學問題的求解:
?
1.?判斷2的冪
若?n?是2的冪(如2、4、8),則二進制表示為?100...0?,滿足 ?n & (n-1) == 0?(如?8(1000) & 7(0111) = 0?)。
?
2.?計算二進制中1的個數(位計數)
方法1:循環檢查每一位(?count += n & 1; n >>= 1?)。
方法2:Brian Kernighan算法(高效):?while n: n &= n-1; count +=1?(每次清除最后一個1)。
應用:漢明距離(兩數二進制不同位的數量,即?bin(x^y).count('1')?)。
?
3.?二進制分解(拆分為2的冪之和)
任何整數?n?都可分解為?n = 2^a + 2^b + ...?(如?5=4+1=2^2+2^0?)。
應用:貪心算法中,用最少的2的冪之和表示?n?(直接取二進制中1的位置)。
?
4.?高低位分離與合并
例如將32位整數的高16位和低16位分離:?high = (x >> 16) & 0xffff; low = x & 0xffff?,常用于哈希、加密等場景。


?
四、數據結構:基于二進制的高效設計


?
部分經典數據結構利用二進制的“分解性”(將問題拆分為2的冪次規模)實現高效操作:
?
1.?二進制索引樹(Fenwick Tree,樹狀數組)
核心思想:將數組索引分解為二進制表示(如?index=5(101)?可分解為?4+1=2^2+2^0?),通過樹狀結構存儲前綴和,支持O(log n)的單點更新和前綴和查詢。
應用:區間和、逆序對計數等。
?
2.?線段樹的二進制優化
線段樹的區間劃分基于“二分”,本質是二進制分解(將區間拆分為2的冪次長度的子區間),其查詢和更新效率(O(log n))依賴于二進制的快速拆分。
?
3.?二進制堆
堆的結構是完全二叉樹,其父子節點索引關系(左子節點?2*i+1?,右子節點?2*i+2?)本質是二進制的左移操作(?i << 1?等價于?2*i?),因此堆的插入、刪除操作可通過位運算快速定位節點。


?
五、算法優化:用位運算替代傳統操作


?
二進制運算的高效性(硬件級支持)可優化算法的時間復雜度:
?
1.?替代算術運算
?
- 乘以/除以2的冪:?x * 8 = x << 3?,?x // 16 = x >> 4?(比乘法/除法快得多)。
?
- 判斷奇偶:?x & 1 == 1?(奇數),比?x % 2?更高效。
?
- 取模2的冪:?x % 8 = x & 7?(因為?8=2^3?,掩碼?7=111?)。
?
2.?變量交換(無需臨時變量)
利用異或特性:?a ^= b; b ^= a; a ^= b?(原理:?a ^ b ^ a = b?)。
?
3.?區間狀態快速更新
例如用二進制表示“開關狀態”,通過?mask ^ (1 << i)?快速翻轉第?i?個開關的狀態,比數組操作更簡潔。


?
六、經典問題中的二進制應用


?
1.?子集和問題
當元素數量?n <= 20?時,可用二進制枚舉所有子集(?2^20 ≈ 1e6?),判斷是否存在和為目標值的子集。
?
2.?最大異或對
給定數組,找一對數使其異或結果最大。解法:按二進制位從高到低構建前綴樹(Trie),對每個數在樹中找能使異或最大的數(每一位盡量取相反值)。
?
3.?位運算dp
例如“統計[0, n]中數字二進制不含連續1的個數”,用dp記錄每一位的狀態(是否為1),通過位轉移避免連續1。
?
4.?格雷碼生成
格雷碼是相鄰數二進制僅差1位的編碼,生成公式:?gray(n) = n ^ (n >> 1)?,利用二進制異或特性直接構造。
?
總結
?
二進制在算法中的應用核心是利用位運算的高效性和二進制表示的結構性,實現從基礎操作到復雜問題的優化。無論是狀態壓縮、數據結構設計,還是數學問題求解,二進制都提供了簡潔且高效的思路,是算法工程師必須掌握的基礎工具。

七、實用的二進制運算技巧

n&(n-1)

將最低位的1置零

6&5 = 4 (110? 101? ->100)

n&(-n)

保留最低位的1,其余位清零

6&-6 = 2 (110)

n|(n-1)

將最低位的1及其右邊的位都置為1

6|5? =7 (110|101->111)

八、leetcode

九、算法講解030【必備】異或運算的騷操作

算法講解030【必備】異或運算的騷操作_嗶哩嗶哩_bilibilihttps://www.bilibili.com/video/BV1LN411z7nu/?spm_id_from=333.1387.collection.video_card.click&vd_source=cdc2a34485eb016f95eae1a314b1a6201.異或:無進位相加

不同為1,相同為0

2.異或運算滿足交換律和結合律

3.0^a=a? ? ? n^n=0

4.

1^0^1^0=1

1^0=1

5.異或運算交換兩個數

a^=b;

b^=a;

a^=b;

6.不用任何判斷語句和比較操作,返回兩個數的最大值?

import mathdef get_max(a, b):return (a + b + math.fabs(a - b)) / 2
int max_with_xor(int a, int b) {int diff = a - b;// 獲取符號位(對于32位整數)int sign = (diff >> 31) & 1;// 使用異或計算最大值return a ^ (sign ^ (a ^ b));
}

無溢出版

int max_with_xor_safe(int a, int b) {// 計算符號位:a和b符號不同時為1,相同時為0int sign_diff = ((a ^ b) >> 31) & 1;// 當a和b符號不同時:// - 若a為正,則a大;若a為負,則b大int result1 = (a >> 31 & 1) ? b : a;// 當a和b符號相同時:// 使用異或方法(此時a-b不會溢出)int diff = a - b;int sign = (diff >> 31) & 1;int result2 = a ^ (sign ^ (a ^ b));// 根據符號是否相同選擇結果(利用異或的特性)return (sign_diff ? result1 : result2);
}

7.找到缺失的數字

原[0,1,2,4]

補全[0,1,2,3,4]

原的異或^補全的異或=缺失的數字

268. 丟失的數字 - 力扣(LeetCode)https://leetcode.cn/problems/missing-number/submissions/8.數組中一種數出現了奇數次,其他的數都出現了偶數次,返回出現了奇數次的數

閹割版

136. 只出現一次的數字 - 力扣(LeetCode)https://leetcode.cn/problems/single-number/submissions/654128520/9.找出數組中兩個出現偶數次的數

先全部異或得到a^b

取出最右側的1

之后樹狀數組也會用到

n&((~n)+1)=n&(-n)

Brian Kernighan算法

n&(n-1)

10.找唯一一個出現次數少于m次的數

看二進制的狀態

11.補充:

計算一個數的二進制表示中 1 的個數

class Solution {
public:// 計算n的二進制表示中1的個數int hammingWeight(int n) {int count = 0;// 當n不為0時,繼續循環while (n != 0) {// 清除最右邊的1n &= n - 1;// 計數加1count++;}return count;}
};

其他方法

int hammingWeight(int n) {int count = 0;for (int i = 0; i < 32; i++) {// 檢查第i位是否為1if ((n & (1 << i)) != 0) {count++;}}return count;
}

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

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

相關文章

PAT 1071 Speech Patterns

題目大意是說給出一個文本&#xff0c;找出里面出現最多的單詞&#xff0c;如果有多個單詞出現次數一樣多&#xff0c;則輸出字典序最小的。 需要注意的是&#xff1a; 給出的文本字符串不僅有數字還有字母&#xff0c;還有一些特殊的字符&#xff0c;還有空格。 而單詞是只包含…

CSS中的 :root 偽類

在CSS中&#xff0c;偽類是一種用于選擇元素特定狀態的選擇器。:root 偽類專門用于選擇文檔的根元素&#xff08;在HTML中通常是<html>元素&#xff09;&#xff0c;它是CSS變量&#xff08;Custom Properties&#xff09;的理想載體&#xff0c;常用于定義全局樣式變量&…

能源行業數字化轉型:邊緣計算網關在油田場景的深度應用

能源行業數字化轉型&#xff1a;邊緣計算網關在油田場景的深度應用能源行業是國民經濟的支柱產業&#xff0c;而油田作為能源生產的重要基地&#xff0c;其數字化轉型對于提高生產效率、降低能耗、減少碳排放具有重要意義。然而&#xff0c;油田往往地處偏遠&#xff0c;油井分…

CAG緩存增強生成與RAG檢索增強生成對比

深度定制 LLM 知識,除了 RAC &#xff0c;現在又有新技術假設有一份200頁的產品手冊,你想讓 LLM 準確回答里面的相關問題,要實現這個目標,除了常用的檢索增強生成技術 rep ,現在有了新思路,緩存增強生成 CAG &#xff0c;它是什么,何時使用.RAG檢索增強是常規套路,CAG緩存增強是…

基于vue、node.js、express的網絡教學系統設計與實現/基于vue、node.js、express的在線學習系統設計與實現

基于vue、node.js、express的網絡教學系統設計與實現/基于vue、node.js、express的在線學習系統設計與實現

享元模式引發的關于ECS和對象池的思考記錄

文章目錄概念概述解決了什么區別與聯系享元模式的某個例子的細節分析概念概述 ECS&#xff08;Entity-Component-System&#xff09; 1、Entity&#xff08;實體&#xff09;&#xff1a;唯一標識符。 2、Component&#xff08;組件&#xff09;&#xff1a;純數據容器&#x…

STM32驅動SG90舵機全解析:從PWM原理到多舵機協同控制

一、SG90舵機核心特性 1.1 基本參數與選型 SG90作為??微型舵機的代表??,憑借其??輕量化設計??(僅9g)和??高性價比??,在機器人、智能小車和云臺系統中廣泛應用: ??關鍵參數對比??: ??參數?? 180定位舵機 360連續旋轉舵機 ??控制目標?? 精確…

goland怎么取消自動刪除未使用的包

1.settings-Go-Imports-取消勾選Optimize imports on the fly2.settings-Tools-取消勾選Optimize imports

halcon基于透視的可變形模型匹配

算子1&#xff0c;create_planar_uncalib_deformable_model_xld***基于平面未校準的輪廓模型算子2&#xff0c;find_planar_uncalib_deformable_model***查找平面未校準可變形模型算子3&#xff0c;projective_trans_contour_xld***將輪廓進行透視變換附加算子 算子4read_conto…

Flink Stream API - 源碼開發需求描述

概述 本文介紹如何基于Flink源碼進行二次開發&#xff0c;實現一個動態規則引擎系統。通過自定義算子和算子協調器&#xff0c;實現數據流的動態規則計算和協調管理。以此更好理解前面介紹的源碼相關文章 項目需求 核心功能 實現一個動態規則引擎&#xff0c;具備以下特性&…

「 CentOS7 安裝部署k8s」

一、Linux系統部署K8s還是非常便利的&#xff0c;只需要掌握Linux常用命令&#xff0c;便可以迅速部署&#xff0c;一起來學習一下吧1、運行以下命令更新系統并安裝必要工具&#xff1a;yum update -y yum install -y yum-utils device-mapper-persistent-data lvm22、安裝Dock…

Disbursement on Quarantine Policy(概率、逆元計算期望)

題目描述There is a train with n rows, and there are m seats per row. All seats are occupied. For some passengers, we know they are being infected with COVID-19 or not. However, for other passengers, we are not sure about their status, and we assume each of…

AI 在金融領域的落地案例

目錄 引言 一、信貸風控&#xff1a;基于 LoRA 的 Qwen-7B 模型微調&#xff08;適配城商行審批場景&#xff09; 場景背景 核心代碼 1. 環境依賴安裝 2. 金融數據集加載與預處理&#xff08;城商行信貸數據&#xff09; 3. LoRA 微調 Qwen-7B 模型 4. 模型推理&#xf…

平衡二叉樹的調整

平衡二叉樹的定義平衡二叉樹&#xff08;balanced binary tree&#xff09;&#xff0c;又稱AVL樹(Adelson-Velskii and Landis)。 一棵平衡二叉樹或者是空樹&#xff0c;或者是具有下列性質的二叉排序樹&#xff1a;① 左子樹與右子樹的高度之差的絕對值小于等于1&#xff1b;…

深入解析:如何設計靈活且可維護的自定義消息機制

深入解析&#xff1a;如何設計靈活且可維護的自定義消息機制 引言 在現代軟件開發中&#xff0c;組件間的通信機制至關重要。無論是前端框架中的組件交互&#xff0c;還是后端服務間的消息傳遞&#xff0c;一個良好的消息機制能顯著提升代碼的可維護性和擴展性。本文將深入探討…

PostgreSQL——用戶管理

PostgreSQL用戶管理一、組角色管理1.1、創建組角色1.2、查看和修改組角色1.3、刪除組角色二、角色的各種權限2.1、LOGIN&#xff08;登錄&#xff09;2.2、SUPERUSER&#xff08;超級用戶&#xff09;3.3、CREATEDB&#xff08;創建數據庫&#xff09;3.4、CREATEROLE&#xff…

東軟8位MCU使用問題總結

簡介用的單片機為ES7P7021&#xff0c;采用8位RISC內核&#xff0c;2KB的FLASH&#xff0c;128bit的RAM。編譯器使用東軟提供的iDesigner&#xff0c;開發過程中編譯器和單片機有一些地方使用時需要注意下。1.RAMclear()函數注意問題/****************************************…

深度學習在訂單簿分析與短期價格預測中的應用探索

一、訂單簿數據特性及預處理 1.1 訂單簿數據結構解析 在金融交易領域&#xff0c;訂單簿是市場微觀結構的集中體現&#xff0c;它記錄了不同價格水平的買賣訂單信息。一個典型的訂單簿由多個層級組成&#xff0c;每個層級包含特定價格上的買單和賣單數量。例如&#xff0c;在某…

Hashmap源碼

目錄 HashMap底層原理 JDK1.8及以后底層結構為&#xff1a;數組鏈表紅黑樹 默認參數 擴容機制 數組 鏈表 紅黑樹 HashMap為什么用紅黑樹不用B樹 HashMap什么時候擴容 HashMap的長度為什么是 2的 N 次方 HashMap底層原理 JDK1.8及以后底層結構為&#xff1a;數組鏈表紅…

【JAVA 字符串常量池、new String的存儲機制、==與equals的區別,以及字符串重新賦值時的指向變化】

系列文章目錄 提示&#xff1a;這里可以添加系列文章的所有文章的目錄&#xff0c;目錄需要自己手動添加 提示&#xff1a;寫完文章后&#xff0c;目錄可以自動生成&#xff0c;如何生成可參考右邊的幫助文檔 文章目錄系列文章目錄代碼原理解錯誤邏輯理解理解與修正&#xff1a…