LeetCode 47 全排列 II 遞迴

2021-09-27 03:55:19 字數 1665 閱讀 5131

難度:中等

給定乙個可包含重複數字的序列,返回所有不重複的全排列。

示例:

輸入: [1,1,2]

輸出:[

[1,1,2],

[1,2,1],

[2,1,1]

]

記錄每個數字還能夠被選擇的次數numcnt,在選擇數字時用numcnt代替used

class

solution

function<

void

(int index)

> generate;

generate =

[&generate,

&nums,

&numcnt,

&now_p,

&all_p]

(int index)

for(

auto

&i : numcnt)}}

;generate(0

);return all_p;}}

;

c++標準庫中有乙個函式next_permutatuin,46和47題都可以用這個水過,這個函式只需要給出乙個排列,就可以返回按照字典序的下乙個排列,而且即使有重複元素也沒問題,它是怎麼實現的呢?cppreference 上給出了一種可能的實現:

template

<

class

bidirit

>

bool

next_permutation

(bidirit first, bidirit last)

if(i == first)

}}

按照字典序,最小的排列是不遞減的排列,最大的排列是不遞增的排列。而且對於任意一種排列,它的右側都有一段不遞增的序列(長度可以是1)假設這段排列右側不遞增的部分的長度是n,那麼按照字典序,緊挨著這個排列的下乙個排列應該是:

看懂了這段**之後我感覺我對這個問題的理解都加深了,把這段**的思想用到這道題裡就有了下面的**。

class

solution

while

(true

)// 使用lower_bound

// auto out = lower_bound(nums.begin() + index + 1, nums.end(), nums[index], greater<>()) - 1;

// swap(nums[index], *out);

int out = nums.

size()

;while

(nums[

--out]

<= nums[index]);

swap

(nums[index]

, nums[out]);

reverse

(nums.

begin()

+ index +

1, nums.

end())

;}};

generate(0

);return all_p;}}

;

LeetCode 47 全排列 II 題解

給定乙個包含重複元素的陣列,求全排列。為了做這道題,首先要理清求全排列的本質,實際上求全排列就是固定前面的數,然後對後面的數進行求解,比如一開始的時候選擇第乙個數,然後對剩下的數進行全排列,這樣相當於轉換為乙個子問題,遞迴求解。那麼對於這個問題,假設我們有1,1,3,4四個數,那麼對於第乙個位置,首...

leetcode 47 全排列 II 回溯

全排列的題首先可以想到用回溯解決。在本題中,需要考慮的有兩點 如何判斷構建的排列陣列是否存在重複,以及如何避免使用重複的元素。避免重複比較簡單,可以構建乙個與nums等長的陣列,用於記錄哪個元素被使用過,這樣在往下遍歷時可以用該陣列進行判斷並避免重複使用。去重則比較麻煩,可以考慮使用jdk自帶的se...

LeetCode47全排列二

昨天沒有寫,今天補上哈。給定乙個可能包含重複數字的集合,返回所有可能的不同全排列。例如,1,1,2 有以下不同全排列 1,1,2 1,2,1 2,1,1 之前寫的是無重複數字的全排列,這次是有重複數字的,這就需要判斷一下是否要進行交換。在加入判斷時,判斷的範圍要注意,因為一開始沒有搞清楚交換的原理啊...