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

我們一起學習排列問題!你會嗎?

開發 前端
當收集元素的數組path的大小達到和nums數組一樣大的時候,說明找到了一個全排列,也表示到達了葉子節點。

[[428071]]

給定一個 沒有重復 數字的序列,返回其所有可能的全排列。

示例:

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

思路

此時我們已經學習了組合問題、 分割回文串和子集問題,接下來看一看排列問題。

相信這個排列問題就算是讓你用for循環暴力把結果搜索出來,這個暴力也不是很好寫。

所以正如我們在關于回溯算法,你該了解這些!所講的為什么回溯法是暴力搜索,效率這么低,還要用它?

因為一些問題能暴力搜出來就已經很不錯了!

我以[1,2,3]為例,抽象成樹形結構如下:

全排列

回溯三部曲

  • 遞歸函數參數

首先排列是有序的,也就是說[1,2] 和[2,1] 是兩個集合,這和之前分析的子集以及組合所不同的地方。

可以看出元素1在[1,2]中已經使用過了,但是在[2,1]中還要在使用一次1,所以處理排列問題就不用使用startIndex了。

但排列問題需要一個used數組,標記已經選擇的元素,如圖橘黃色部分所示:

全排列

代碼如下:

  1. vector<vector<int>> result; 
  2. vector<int> path; 
  3. void backtracking (vector<int>& nums, vector<bool>& used) 
  • 遞歸終止條件

全排列

可以看出葉子節點,就是收割結果的地方。

那么什么時候,算是到達葉子節點呢?

當收集元素的數組path的大小達到和nums數組一樣大的時候,說明找到了一個全排列,也表示到達了葉子節點。

代碼如下:

  1. // 此時說明找到了一組 
  2. if (path.size() == nums.size()) { 
  3.     result.push_back(path); 
  4.     return
  • 單層搜索的邏輯

這里和組合問題、切割問題和子集問題最大的不同就是for循環里不用startIndex了。

因為排列問題,每次都要從頭開始搜索,例如元素1在[1,2]中已經使用過了,但是在[2,1]中還要再使用一次1。

而used數組,其實就是記錄此時path里都有哪些元素使用了,一個排列里一個元素只能使用一次。

代碼如下:

  1. for (int i = 0; i < nums.size(); i++) { 
  2.     if (used[i] == truecontinue; // path里已經收錄的元素,直接跳過 
  3.     used[i] = true
  4.     path.push_back(nums[i]); 
  5.     backtracking(nums, used); 
  6.     path.pop_back(); 
  7.     used[i] = false

整體C++代碼如下:

  1. class Solution { 
  2. public
  3.     vector<vector<int>> result; 
  4.     vector<int> path; 
  5.     void backtracking (vector<int>& nums, vector<bool>& used) { 
  6.         // 此時說明找到了一組 
  7.         if (path.size() == nums.size()) { 
  8.             result.push_back(path); 
  9.             return
  10.         } 
  11.         for (int i = 0; i < nums.size(); i++) { 
  12.             if (used[i] == truecontinue; // path里已經收錄的元素,直接跳過 
  13.             used[i] = true
  14.             path.push_back(nums[i]); 
  15.             backtracking(nums, used); 
  16.             path.pop_back(); 
  17.             used[i] = false
  18.         } 
  19.     } 
  20.     vector<vector<int>> permute(vector<int>& nums) { 
  21.         result.clear(); 
  22.         path.clear(); 
  23.         vector<bool> used(nums.size(), false); 
  24.         backtracking(nums, used); 
  25.         return result; 
  26.     } 
  27. }; 

總結

大家此時可以感受出排列問題的不同:

  • 每層都是從0開始搜索而不是startIndex
  • 需要used數組記錄path里都放了哪些元素了

排列問題是回溯算法解決的經典題目,大家可以好好體會體會。

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

 

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

2021-05-31 09:23:04

管道模式責任鏈

2021-05-19 10:37:16

WebFlux 前置工具

2022-02-14 10:16:22

Axios接口HTTP

2010-07-16 10:14:29

信博會國際信息技術博覽會

2025-01-13 00:00:00

配置Redis腦裂

2024-02-28 08:41:51

Maven沖突版本

2021-11-26 09:44:42

鏈表節點定位

2021-05-20 07:15:34

RSA-PSS算法簽名

2022-12-01 09:59:57

內核觀測性方法

2023-03-28 07:32:37

2023-03-26 12:45:52

Linux內核頭文件

2022-06-15 08:00:50

磁盤RedisRocketMQ

2023-10-26 08:38:43

SQL排名平分分區

2023-05-29 09:07:10

SQLpageSize主鍵

2021-03-18 00:04:13

C# 類型數據

2021-12-14 09:34:31

丑數順序指針

2023-11-13 18:36:04

知識抽取NER

2023-10-31 14:04:17

Rust類型編譯器

2023-04-26 22:52:19

視覺人臉檢測人臉對齊

2022-03-31 18:59:43

數據庫InnoDBMySQL
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 超碰人人插 | 欧美炮房 | 天天躁日日躁狠狠的躁天龙影院 | 国产69精品久久久久777 | 欧美激情久久久 | 欧美亚洲在线 | www国产成人免费观看视频,深夜成人网 | 欧美日韩国产在线 | 尤物视频在线免费观看 | 国产精品视频播放 | 国产精品久久久久国产a级 欧美日韩国产免费 | 国产欧美久久精品 | 亚洲成人一区二区在线 | 亚洲国产偷 | 欧美一区二区免费电影 | 午夜影院中文字幕 | 在线观看亚洲专区 | 亚洲午夜电影 | 成人欧美一区二区三区黑人孕妇 | a爱视频| 国产一区二区三区在线免费 | 九九热这里只有精品6 | aaaa网站| 欧州一区二区三区 | 超碰成人免费观看 | 国产精品高清一区二区三区 | 在线久草| 亚洲一区| 一区二区三区四区日韩 | 香蕉大人久久国产成人av | 国产精久久久久久久妇剪断 | 天堂网色| 狠狠干天天干 | 7777精品伊人久久精品影视 | 久久国产精品一区二区三区 | 成人免费视频一区二区 | 一区二区视频在线 | 中文字幕第90页 | 黑人巨大精品欧美一区二区免费 | 亚洲一区播放 | www.日本国产|