成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

子集問題其實就是模板題!你知道嗎?

網絡
如果把 子集問題、組合問題、分割問題都抽象為一棵樹的話,那么組合問題和分割問題都是收集樹的葉子節點,而子集問題是找樹的所有節點!

[[426614]]

認識本質之后,這就是一道模板題

子集

力扣題目鏈接:https://leetcode-cn.com/problems/subsets/

給定一組不含重復元素的整數數組 nums,返回該數組所有可能的子集(冪集)。

說明:解集不能包含重復的子集。

示例:

輸入: nums = [1,2,3]

輸出: [ [3], [1], [2], [1,2,3], [1,3], [2,3], [1,2], [] ]

思路

求子集問題和77.組合和131.分割回文串又不一樣了。

如果把 子集問題、組合問題、分割問題都抽象為一棵樹的話,那么組合問題和分割問題都是收集樹的葉子節點,而子集問題是找樹的所有節點!

其實子集也是一種組合問題,因為它的集合是無序的,子集{1,2} 和 子集{2,1}是一樣的。

那么既然是無序,取過的元素不會重復取,寫回溯算法的時候,for就要從startIndex開始,而不是從0開始!

有同學問了,什么時候for可以從0開始呢?

求排列問題的時候,就要從0開始,因為集合是有序的,{1, 2} 和{2, 1}是兩個集合,排列問題我們后續的文章就會講到的。

以示例中nums = [1,2,3]為例把求子集抽象為樹型結構,如下:

子集

從圖中紅線部分,可以看出遍歷這個樹的時候,把所有節點都記錄下來,就是要求的子集集合。

回溯三部曲

  • 遞歸函數參數

全局變量數組path為子集收集元素,二維數組result存放子集組合。(也可以放到遞歸函數參數里)

遞歸函數參數在上面講到了,需要startIndex。

代碼如下:

  1. vector<vector<int>> result; 
  2. vector<int> path; 
  3. void backtracking(vector<int>& nums, int startIndex) { 

遞歸終止條件

從圖中可以看出:

子集

剩余集合為空的時候,就是葉子節點。

那么什么時候剩余集合為空呢?

就是startIndex已經大于數組的長度了,就終止了,因為沒有元素可取了,代碼如下:

  1. if (startIndex >= nums.size()) { 
  2.     return

其實可以不需要加終止條件,因為startIndex >= nums.size(),本層for循環本來也結束了。

  • 單層搜索邏輯

求取子集問題,不需要任何剪枝!因為子集就是要遍歷整棵樹。

那么單層遞歸邏輯代碼如下:

  1. for (int i = startIndex; i < nums.size(); i++) { 
  2.     path.push_back(nums[i]);    // 子集收集元素 
  3.     backtracking(nums, i + 1);  // 注意從i+1開始,元素不重復取 
  4.     path.pop_back();            // 回溯 

C++代碼

根據關于回溯算法,你該了解這些!給出的回溯算法模板:

  1. void backtracking(參數) { 
  2.     if (終止條件) { 
  3.         存放結果; 
  4.         return
  5.     } 
  6.  
  7.     for (選擇:本層集合中元素(樹中節點孩子的數量就是集合的大小)) { 
  8.         處理節點; 
  9.         backtracking(路徑,選擇列表); // 遞歸 
  10.         回溯,撤銷處理結果 
  11.     } 

可以寫出如下回溯算法C++代碼:

  1. class Solution { 
  2. private: 
  3.     vector<vector<int>> result; 
  4.     vector<int> path; 
  5.     void backtracking(vector<int>& nums, int startIndex) { 
  6.         result.push_back(path); // 收集子集,要放在終止添加的上面,否則會漏掉自己 
  7.         if (startIndex >= nums.size()) { // 終止條件可以不加 
  8.             return
  9.         } 
  10.         for (int i = startIndex; i < nums.size(); i++) { 
  11.             path.push_back(nums[i]); 
  12.             backtracking(nums, i + 1); 
  13.             path.pop_back(); 
  14.         } 
  15.     } 
  16. public
  17.     vector<vector<int>> subsets(vector<int>& nums) { 
  18.         result.clear(); 
  19.         path.clear(); 
  20.         backtracking(nums, 0); 
  21.         return result; 
  22.     } 
  23. }; 

在注釋中,可以發現可以不寫終止條件,因為本來我們就要遍歷整顆樹。

有的同學可能擔心不寫終止條件會不會無限遞歸?

并不會,因為每次遞歸的下一層就是從i+1開始的。

本文轉載自微信公眾號「代碼隨想錄」,可以通過以下二維碼關注。轉載本文請聯系代碼隨想錄公眾號。

 

責任編輯:武曉燕 來源: 代碼隨想錄
相關推薦

2021-10-08 11:13:41

子集問題數據結構算法

2014-01-22 09:17:12

2023-12-20 08:23:53

NIO組件非阻塞

2023-12-12 08:41:01

2023-04-26 10:21:04

2024-04-30 09:02:48

2024-05-28 09:12:10

2024-04-07 00:00:00

ESlint命令變量

2024-01-09 07:29:05

Argo代碼庫應用程序

2020-10-28 11:20:55

vue項目技

2019-12-12 09:23:29

Hello World操作系統函數庫

2017-10-16 13:45:04

2024-07-30 08:22:47

API前端網關

2022-05-27 08:55:15

工具自動化軟件

2022-03-10 08:25:27

JavaScrip變量作用域

2022-06-24 08:20:04

CAP網絡通信

2021-02-02 08:21:28

網絡面試通信

2024-10-10 16:53:53

守護線程編程

2019-06-14 15:36:13

Windows 10安全PC

2024-04-07 00:00:03

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 这里只有精品999 | 久久久久久久久毛片 | 成年人在线视频 | 亚洲草草视频 | 亚洲国产成人精品久久久国产成人一区 | 美女张开腿露出尿口 | 欧美 日韩 综合 | 欧美一级久久 | 欧美在线不卡 | 免费a国产| 涩涩视频在线观看 | 中文字幕精品一区 | 99精品久久| 91视频在线观看 | 四虎永久免费影院 | 自拍偷拍亚洲一区 | 黄色一级视频免费 | 国产激情一区二区三区 | 亚洲在线久久 | 色av一区二区 | 精品国产99 | 97人人干| 久久精品亚洲欧美日韩久久 | 成人在线一区二区三区 | 七七婷婷婷婷精品国产 | 久久久成人一区二区免费影院 | 国产乱码精品一区二区三区忘忧草 | 高清国产一区二区 | 国产夜恋视频在线观看 | 亚洲情视频| 久久精品国产免费高清 | 国产高清在线观看 | 亚洲精品久久久 | 久久久999成人 | 欧产日产国产精品国产 | 欧美国产在线一区 | 97视频在线观看免费 | 成人免费区一区二区三区 | 欧美日日| 欧美一区二区三区视频 | 欧美视频 亚洲视频 |