【LeetCode 熱題 100】78. 子集——(解法三)位運算

Problem: 78. 子集
題目:給你一個整數數組 nums ,數組中的元素 互不相同 。返回該數組所有可能的子集(冪集)。
解集 不能 包含重復的子集。你可以按 任意順序 返回解集。

文章目錄

  • 整體思路
  • 完整代碼
  • 時空復雜度
    • 時間復雜度:O(N * 2^N)
    • 空間復雜度:O(N) (不考慮輸出數組)

整體思路

這段代碼同樣旨在解決 “子集 (Subsets)” 問題。與前面基于回溯/DFS的遞歸解法不同,此版本采用了一種完全不同的、基于 位掩碼(Bitmask) 的迭代方法。這種方法非常巧妙,它將“生成子集”的問題與“二進制數的表示”完美地對應起來。

算法的核心思想是:

  1. 子集與二進制數的映射關系

    • 一個包含 n 個元素的集合,其所有子集的數量是 2^n
    • 巧合的是,從 02^n - 1,也正好有 2^n 個不同的整數。
    • 我們可以將這 n 個元素與一個 n 位的二進制數的每一位進行一一對應。例如,nums = [a, b, c]n=3。我們可以用一個 3 位的二進制數來表示一個子集:
      • 第 0 位對應元素 a
      • 第 1 位對應元素 b
      • 第 2 位對應元素 c
    • 規則:如果二進制數的某一位是 1,則表示對應的元素被選中加入子集;如果是 0,則表示不選
    • 示例
      • 二進制 000 (十進制 0) -> {} (空集)
      • 二進制 001 (十進制 1) -> {a}
      • 二進制 010 (十進制 2) -> {b}
      • 二進制 101 (十進制 5) -> {a, c}
      • 二進制 111 (十進制 7) -> {a, b, c}
    • 這樣,從 02^n - 1 的每一個整數,都唯一地對應著一個子集。
  2. 算法實現步驟

    • 外層循環:算法的主體是一個 for 循環,它從 i = 0 遍歷到 (1 << n) - 1。這里的 (1 << n) 就是 2^n。這個循環變量 i 就充當了位掩碼,它的二進制表示決定了當前要生成哪個子集。
    • 內層循環與位運算
      • 對于每一個位掩碼 i,算法進入一個內層循環,從 j = 0n-1,檢查 i 的每一位。
      • 檢查第 j:通過位運算 (i >> j & 1) == 1 來檢查 i 的第 j 位是否為 1。
        • i >> j: 將 i 右移 j 位,使得原來的第 j 位移動到最右邊(第 0 位)。
        • & 1: 將右移后的結果與 1 進行按位與操作。如果原來的第 j 位是 1,結果就是 1;如果是 0,結果就是 0
      • 構建子集:如果檢查結果為 1,說明 nums[j] 這個元素應該被包含在當前子集中,于是將其加入到臨時的 subset 列表中。
    • 收集結果:內層循環結束后,subset 列表就構建完畢了,將其加入到最終的結果列表 ans 中。

通過這種方式,算法以一種確定性的、非遞歸的方式,系統地生成了所有 2^n 個子集。

完整代碼

class Solution {/*** 計算給定數組的所有子集(冪集)。* (位掩碼迭代法)* @param nums 不含重復元素的整數數組* @return 包含所有子集的列表*/public List<List<Integer>> subsets(int[] nums) {int n = nums.length;// 預先設定ArrayList的容量為 2^n,可以提高性能,避免多次內部擴容。// (1 << n) 是 2^n 的高效寫法。List<List<Integer>> ans = new ArrayList<>(1 << n);// 步驟 1: 外層循環遍歷所有可能的子集,用整數 0 到 2^n - 1 作為位掩碼。for (int i = 0; i < (1 << n); i++) {// 為每個位掩碼創建一個新的子集列表。List<Integer> subset = new ArrayList<>();// 步驟 2: 內層循環檢查位掩碼 i 的每一位,以確定哪些元素應加入子集。for (int j = 0; j < n; j++) {// 關鍵的位運算:檢查 i 的第 j 位是否為 1。// (i >> j) 將 i 的第 j 位移到最右邊。// (& 1)   檢查最右邊一位是否為 1。if ((i >> j & 1) == 1) {// 如果第 j 位為 1,則將 nums[j] 加入到當前子集中。subset.add(nums[j]);}}// 將構建好的子集加入到最終結果列表中。ans.add(subset);}return ans;}
}

時空復雜度

時間復雜度:O(N * 2^N)

  1. 外層循環for (int i = 0; i < (1 << n); i++) 執行 2^N 次。
  2. 內層循環for (int j = 0; j < n; j++) 執行 N 次。
  3. 循環內部操作:位運算和 subset.add() 都是 O(1) 的操作。

綜合分析
算法的總操作次數是外層循環次數乘以內層循環次數,即 2^N * N
因此,總的時間復雜度為 O(N * 2^N)。這與回溯法的時間復雜度量級是相同的,因為問題的內在計算量就是這么多。

空間復雜度:O(N) (不考慮輸出數組)

  1. 主要存儲開銷:我們分析的是額外輔助空間
    • List<Integer> subset: 在每次外層循環中,都會創建一個臨時的 subset 列表。在任意時刻,只有一個 subset 列表存在于內存中。這個列表的最大長度為 N(當位掩碼為 11...1 時)。因此,這部分空間是 O(N)
    • 其他變量 n, i, j 都是常數空間。

綜合分析
如果不考慮存儲最終結果的 ans 列表(其空間為 O(N * 2^N)),算法所需的額外輔助空間主要由臨時的 subset 列表決定。因此,其空間復雜度為 O(N)

參考靈神

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

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

相關文章

XCKU035?1SFVA784C Xilinx FPGA KintexUltraScale AMD

XCKU035?1SFVA784C 屬于 Xilinx Kintex UltraScale 系列&#xff0c;基于領先的 20?nm FinFET 技術制程&#xff0c;旨在為中高端應用提供卓越的性能與功耗平衡。該器件采用 784?ball Fine?pitch BGA&#xff08;SFVA784&#xff09;封裝&#xff0c;速度等級?1&#xff0…

Encore.ts:下一代高性能 TypeScript 后端框架的崛起

在 Node.js 生態系統中&#xff0c;后端框架的選擇直接影響 API 的性能、開發體驗和可維護性。近年來&#xff0c;Elysia.js、Hono、Fastify 等框架憑借各自的優化策略嶄露頭角&#xff0c;而 Encore.ts 則憑借 Rust TypeScript 混合架構&#xff0c;在性能上實現了質的飛躍。…

【IP地址】IP歸屬地查詢驅動企業實時戰略調整

動態市場感知與資源調度優化? IP歸屬地的實時分析為企業提供了市場需求的動態變化圖。 基于實時數據處理框架&#xff0c;企業可將IP歸屬地數據與用戶訪問量、轉化率等指標關聯計算&#xff0c;生成區域市場活躍度熱力圖。 當某區域IP訪問量在1小時內激增300%且停留時長提升至…

[Bug | Cursor] import error: No module named ‘data‘

import error: No module named ‘data’ Folder Structure root folder data folder dataloader.py src folder train.py <- where we try to import the dataloader.pyFailed Script ROOT_DIR Path(__file__).parent.parent os.chdir(ROOT_DIR) print(f"Using root…

#Linux權限管理:從“Permission denied“到系統安全大師

引入 Linux 作為多用戶系統&#xff0c;權限是系統安全的第一道防線。不合理的權限設置可能導致&#xff1a; 敏感文件泄露&#xff08;如數據庫密碼被讀取&#xff09;誤刪核心數據&#xff08;目錄寫權限失控&#xff09;權限漏洞被利用&#xff08;如 SUID 提權攻擊&#…

電腦重置一次對電腦傷害大嗎

在日常使用電腦的過程中&#xff0c;很多用戶或多或少都遇到過系統卡頓、軟件沖突、病毒入侵等問題。當電腦變得“越來越慢”或頻繁出錯時&#xff0c;一些用戶會考慮“重置電腦”&#xff0c;也就是將電腦恢復到出廠設置。但不少人心中也有疑問&#xff1a;重置電腦一次&#…

CSP-J系列【2024】P11229 [CSP-J 2024] 小木棍題解

題目描述小 S 喜歡收集小木棍。在收集了 n 根長度相等的小木棍之后&#xff0c;他閑來無事&#xff0c;便用它們拼起了數字。用小木棍拼每種數字的方法如下圖所示。現在小 S 希望拼出一個正整數&#xff0c;滿足如下條件&#xff1a;拼出這個數恰好使用 n 根小木棍&#xff1b;…

C# 繼承 虛方法

繼承 虛方法 &#xff08;重寫&#xff09; virtual 虛方法的關鍵字 override 重寫的關鍵字 練習&#xff1a; 繼承 繼承&#xff1a;很多類有相似的數據 相同的屬性 相同的方法 也有不同的 這個時候就可以使用繼承 讓多個類去繼承自某個具有相同數據的基類(父類) 這…

Java 堆(優先級隊列)

文章目錄優先級隊列模擬實現優先級隊列向下調整建堆向上調整建堆堆的刪除priorityQueue構造方法大根堆和小根堆的向上調整比較方法擴容面試題堆排序優先級隊列 priorityqueue&#xff1a;底層是一顆完全二叉樹 小根堆&#xff1a;根比左右孩子都小大根堆&#xff1a;根比左右…

在.NET Core API 微服務中使用 gRPC:從通信模式到場景選型

目錄 一、gRPC 基礎&#xff1a;為什么它適合微服務&#xff1f; 二、gRPC 的四種通信模式及.NET Core 實現 1. 一元 RPC&#xff08;Unary RPC&#xff09;&#xff1a;最基礎的請求 - 響應模式 2. 服務器流式 RPC&#xff08;Server Streaming RPC&#xff09;&#xff1…

HTML零基礎快速入門教程(詳細篇)

本文詳細介紹HTML零基礎快速入門的基礎知識&#xff0c;包括HTML的介紹、語言的一些實際作用、語法規范注意&#xff0c;如標簽結構、標簽屬性、大小寫不敏感等&#xff0c;還介紹了HTML文件的具體書寫規則&#xff0c;如文件擴展名、文檔類型聲明和HTML結構以及具體的一些HTML…

LLM評測框架Ragas:SQL指標(解決了Ollama推理框架不支持的問題)

SQL類的度量指標是指運行SQL后的結果和預期之間的一個度量值。 datacompy score datacompy score 使用DataCompy(一個比較pandas的數據格式的python類,所以需要按照datacompy:pip install datacompy),默認是按照rows比較,也可以設置按照columns比較,這個事通過mode參數…

ubuntu24 ros2 jazzy

安裝2 software & update 選擇其它 安裝 一、前提準備 檢查操作系統版本&#xff1a; 確保你的系統版本是Ubuntu 24.04。你可以通過運行lsb_release -a命令來檢查當前的系統版本。 設置UTF-8支持&#xff1a; ROS 2需要UTF-8編碼支持。你可以通過以下命令來檢查和設置UTF…

設備虛擬化技術

設備虛擬化技術概述設備虛擬化技術通過軟件模擬物理硬件設備&#xff0c;使多個操作系統或應用程序能夠共享同一臺物理設備。它廣泛應用于云計算、服務器整合和測試環境等領域。核心目標是提高資源利用率、隔離性和靈活性。?當接入的用戶數增加到原交換機端口密度不能滿足接入…

開發避坑短篇(3):解決@vitejs plugin-vue@5.0.5對Vite^5.0.0的依賴沖突

異常信息 # npm resolution error reportWhile resolving:system3.8.8 Found: vite6.2.3 node_modules/vitedev vite"6.2.3" from the root projectCould not resolve dependency: peer vite"^5.0.0" from vitejs/plugin-vue5.0.5 node_modules/vitejs/plu…

k8s快速部署(親測無坑)

文章目錄k8s快速部署&#xff08;親測無坑&#xff09;一、網絡劃分二、CentOS7設置 標題固定IP和阿里云YUM源三、主機環境配置四、虛擬機的拷貝五、安裝docker(每臺主機都需要安裝)六、安裝kubelet,kubeadm,kubectl(每臺機器都需要執行)遇到的問題參考文檔k8s快速部署&#xf…

簡易RAG問答引擎的構建與體驗

RAG&#xff08;檢索增強生成&#xff09;是結合檢索與生成式 AI 的技術框架。核心邏輯是先從外部知識庫精準檢索相關信息&#xff0c;再將其作為上下文輸入大模型生成回答。技術上依賴檢索引擎&#xff08;如向量數據庫、BM25&#xff09;、大語言模型&#xff08;如 GPT、LLa…

C++11特性學習 Day1

nullptr對于c中null (void*)0&#xff0c;所以在為函數傳參傳入0時&#xff0c;無法清楚地分辨是int類型的0還是指的是空指針null在C11中清晰的將空指針變為了nullptr&#xff0c;0專指int型的數字0override關鍵字在子類中對父類的函數的覆寫之后加上override關鍵字&#xff0…

微算法科技(NASDAQ: MLGO)探索優化量子糾錯算法,提升量子算法準確性

隨著量子計算技術的飛速發展&#xff0c;量子計算機在解決復雜計算問題上的潛力日益顯現。然而&#xff0c;量子計算面臨的一個重大挑戰是量子比特的脆弱性&#xff0c;即量子比特容易受到環境噪聲和干擾的影響&#xff0c;導致量子態的塌縮和計算結果的錯誤。微算法科技&#…

MongoDB數據庫詳解-針對大型分布式項目采用的原因以及基礎原理和發展-卓伊凡|貝貝|莉莉

MongoDB數據庫詳解-針對大型分布式項目采用的原因以及基礎原理和發展-卓伊凡|貝貝|莉莉由于老產品即時通訊私有化軟件就是采用MongoDB &#xff0c;但是版本實在太低&#xff0c;要做大更新&#xff0c;其次針對10年前完美運營的項目來到10年后的現在就不一定行&#xff0c;優雅…