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

排列問題也要去重了!

開發 前端
如果對回溯算法基礎還不了解的話,我還特意錄制了一期視頻:帶你學透回溯算法(理論篇) 可以結合題解和視頻一起看,希望對大家理解回溯算法有所幫助。

[[428322]]

全排列 II

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

給定一個可包含重復數字的序列 nums ,按任意順序 返回所有不重復的全排列。

示例 1:

  • 輸入:nums = [1,1,2]
  • 輸出:[[1,1,2], [1,2,1], [2,1,1]]

示例 2:

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

提示:

  • 1 <= nums.length <= 8
  • -10 <= nums[i] <= 10

思路

如果對回溯算法基礎還不了解的話,我還特意錄制了一期視頻:帶你學透回溯算法(理論篇) 可以結合題解和視頻一起看,希望對大家理解回溯算法有所幫助。

這道題目和全排列的區別在與給定一個可包含重復數字的序列,要返回所有不重復的全排列。

這里又涉及到去重了。

在組合總和II 、子集II我們分別詳細講解了組合問題和子集問題如何去重。

那么排列問題其實也是一樣的套路。

還要強調的是去重一定要對元素經行排序,這樣我們才方便通過相鄰的節點來判斷是否重復使用了。

我以示例中的 [1,1,2]為例 (為了方便舉例,已經排序)抽象為一棵樹,去重過程如圖:

全排列II1

圖中我們對同一樹層,前一位(也就是nums[i-1])如果使用過,那么就進行去重。

一般來說:組合問題和排列問題是在樹形結構的葉子節點上收集結果,而子集問題就是取樹上所有節點的結果。

在46.全排列中已經詳解講解了排列問題的寫法,在40.組合總和II 、90.子集II中詳細講解的去重的寫法,所以這次我就不用回溯三部曲分析了,直接給出代碼,如下:

C++代碼

  1. class Solution { 
  2. private: 
  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.             // used[i - 1] == true,說明同一樹支nums[i - 1]使用過 
  13.             // used[i - 1] == false,說明同一樹層nums[i - 1]使用過 
  14.             // 如果同一樹層nums[i - 1]使用過則直接跳過 
  15.             if (i > 0 && nums[i] == nums[i - 1] && used[i - 1] == false) { 
  16.                 continue
  17.             } 
  18.             if (used[i] == false) { 
  19.                 used[i] = true
  20.                 path.push_back(nums[i]); 
  21.                 backtracking(nums, used); 
  22.                 path.pop_back(); 
  23.                 used[i] = false
  24.             } 
  25.         } 
  26.     } 
  27. public
  28.     vector<vector<int>> permuteUnique(vector<int>& nums) { 
  29.         result.clear(); 
  30.         path.clear(); 
  31.         sort(nums.begin(), nums.end()); // 排序 
  32.         vector<bool> used(nums.size(), false); 
  33.         backtracking(nums, used); 
  34.         return result; 
  35.     } 
  36. }; 

拓展

大家發現,去重最為關鍵的代碼為:

  1. if (i > 0 && nums[i] == nums[i - 1] && used[i - 1] == false) { 
  2.     continue

如果改成 used[i - 1] == true, 也是正確的!,去重代碼如下:

  1. if (i > 0 && nums[i] == nums[i - 1] && used[i - 1] == true) { 
  2.     continue

這是為什么呢,就是上面我剛說的,如果要對樹層中前一位去重,就用used[i - 1] == false,如果要對樹枝前一位去重用used[i - 1] == true。

對于排列問題,樹層上去重和樹枝上去重,都是可以的,但是樹層上去重效率更高!

這么說是不是有點抽象?

來來來,我就用輸入: [1,1,1] 來舉一個例子。

樹層上去重(used[i - 1] == false),的樹形結構如下:

全排列II2

樹枝上去重(used[i - 1] == true)的樹型結構如下:

全排列II

大家應該很清晰的看到,樹層上對前一位去重非常徹底,效率很高,樹枝上對前一位去重雖然最后可以得到答案,但是做了很多無用搜索。

總結

這道題其實還是用了我們之前講過的去重思路,但有意思的是,去重的代碼中,這么寫:

  1. if (i > 0 && nums[i] == nums[i - 1] && used[i - 1] == false) { 
  2.     continue

和這么寫:

  1. if (i > 0 && nums[i] == nums[i - 1] && used[i - 1] == true) { 
  2.     continue

都是可以的,這也是很多同學做這道題目困惑的地方,知道used[i - 1] == false也行而used[i - 1] == true也行,但是就想不明白為啥。

所以我通過舉[1,1,1]的例子,把這兩個去重的邏輯分別抽象成樹形結構,大家可以一目了然:為什么兩種寫法都可以以及哪一種效率更高!

是不是豁然開朗了!!

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

 

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

2021-10-08 11:13:41

子集問題數據結構算法

2020-07-24 10:11:19

AI 數據人工智能

2021-12-29 06:24:16

AI審稿人工智能

2021-09-29 07:41:27

前端技術編程

2022-05-05 09:23:21

裁員程序員危機

2021-11-19 07:54:40

前端

2019-11-14 22:04:09

AIJohn CarmacVR

2019-04-16 14:12:29

AI機器學習TensorFlow

2010-05-11 11:04:11

曹重英

2023-02-09 15:30:35

特斯拉AI

2014-12-17 09:57:39

2021-11-09 11:56:25

模式數組排序

2020-12-09 15:26:00

人工智能律師互聯網

2024-08-30 08:15:59

VueAI工具

2015-05-27 10:11:04

4G

2009-10-16 13:04:18

網絡綜合布線

2017-05-31 13:40:22

人工智能個人助手算法分析

2025-06-03 01:00:00

宇樹合作伙伴資本市場

2015-07-27 09:57:47

iOS捆綁應用

2016-08-04 14:49:38

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 综合色影院| 一区二区国产在线观看 | 成人在线免费观看 | 亚洲日本一区二区三区四区 | 天天视频一区二区三区 | 黄免费观看视频 | 国产精品免费av | 岛国av免费在线观看 | 在线中文视频 | 亚洲欧美日韩精品久久亚洲区 | 亚州成人 | 欧美福利专区 | 欧美精品一区二区在线观看 | 久久久久久亚洲 | 亚洲综合资源 | 国产精品一区二区不卡 | 国产亚洲精品精品国产亚洲综合 | 日本三级精品 | 五月婷婷婷 | 中文字幕综合 | 欧美日韩国产综合在线 | 国产精品三级久久久久久电影 | 日韩久久久久 | 日韩靠逼| 国产精品一区三区 | 波多野结衣一区二区 | 中文字幕亚洲精品 | 国产一区二区三区不卡av | 99视频在线播放 | 9999久久 | 天天澡天天狠天天天做 | 日本网站免费在线观看 | 91精品91久久久 | 毛片一级网站 | 欧美日韩一本 | 毛片网络| 精品1区2区 | 亚洲网站在线播放 | 97超碰成人 | 精品区 | 久久久高清 |