摘要:每一輪搜索選擇一個數(shù)加入列表中,同時我們還要維護一個全局的布爾數(shù)組,來標(biāo)記哪些元素已經(jīng)被加入列表了,這樣在下一輪搜索中要跳過這些元素。
Permutations I
交換法 復(fù)雜度Given a collection of numbers, return all possible permutations.
For example, [1,2,3] have the following permutations: [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], and [3,2,1].
時間 O(N^2) 空間 O(N) 遞歸棧
思路置換實際上是給出所有的排列方式,同樣是用深度優(yōu)先搜索,不過為了避免重復(fù)選擇的情況,我們要保證兩點:第一,所有數(shù)必須是數(shù)組中的,第二,數(shù)組中每個數(shù)只能用不多于也不少于一次。如果我們要多帶帶寫一個函數(shù),來判斷下一輪搜索該選擇哪一個數(shù)就很麻煩了。這里有一個技巧,我們可以只將數(shù)兩兩交換,不過交換時只能跟自己后面的交換。
代碼public class Solution { List深度優(yōu)先搜索 復(fù)雜度> res; public List
> permute(int[] nums) { res = new LinkedList
>(); helper(nums, 0); return res; } public void helper(int[] nums, int i){ // 找到轉(zhuǎn)置完成后的解,將其存入列表中 if(i == nums.length - 1){ List
list = new LinkedList (); for(int j = 0; j < nums.length; j++){ list.add(nums[j]); } res.add(list); } // 將當(dāng)前位置的數(shù)跟后面的數(shù)交換,并搜索解 for(int j = i; j < nums.length; j++){ swap(nums, i , j); helper(nums, i + 1); swap(nums, i, j); } } private void swap(int[] nums, int i, int j){ int tmp = nums[i]; nums[i] = nums[j]; nums[j] = tmp; } }
時間 O(N) 空間 O(N) 遞歸棧
思路我們還可以簡單的使用深度優(yōu)先搜索來解決這題。每一輪搜索選擇一個數(shù)加入列表中,同時我們還要維護一個全局的布爾數(shù)組,來標(biāo)記哪些元素已經(jīng)被加入列表了,這樣在下一輪搜索中要跳過這些元素。
代碼public class Solution { ListPermutations II> res; boolean[] used; public List
> permute(int[] nums) { res = new LinkedList
>(); used = new boolean[nums.length]; List
tmp = new LinkedList (); helper(nums, tmp); return res; } private void helper(int[] nums, List tmp){ if(tmp.size() == nums.length){ List list = new LinkedList (tmp); res.add(list); } else { for(int idx = 0; idx < nums.length; idx++){ // 遇到已經(jīng)加過的元素就跳過 if(used[idx]){ continue; } // 加入該元素后繼續(xù)搜索 used[idx] = true; tmp.add(nums[idx]); helper(nums, tmp); tmp.remove(tmp.size()-1); used[idx] = false; } } } }
深度優(yōu)先搜索 復(fù)雜度Given a collection of numbers that might contain duplicates, return all possible unique permutations.
For example, [1,1,2] have the following unique permutations: [1,1,2], [1,2,1], and [2,1,1].
時間 O(N) 空間 O(N) 遞歸棧
思路這題和上題的深度優(yōu)先搜索很相似,區(qū)別在于:1、要先將數(shù)組排序,確保重復(fù)的元素是在一起的。2、除了不能加入之前出現(xiàn)過的元素之外,還不能加入本輪搜索中出現(xiàn)過的元素。如何判斷哪些元素本輪出現(xiàn)過呢?我們加過一個數(shù)字并搜索后,在這一輪中把剩余的重復(fù)數(shù)字都跳過就行了,保證每一輪只有一個unique的數(shù)字出現(xiàn)。這和Combination Sum II中跳過重復(fù)元素的方法是一樣的,注意要判斷nums[i] == nums[i + 1],因為for循環(huán)結(jié)束時i還會額外加1,我們要把i留在最后一個重復(fù)元素處。
代碼public class Solution { List> res; boolean[] used; public List
> permuteUnique(int[] nums) { res = new LinkedList
>(); used = new boolean[nums.length]; Arrays.sort(nums); List
tmp = new LinkedList (); helper(nums, tmp); return res; } private void helper(int[] nums, List tmp){ if(tmp.size() == nums.length){ List list = new LinkedList (tmp); res.add(list); } else { for(int idx = 0; idx < nums.length; idx++){ // 遇到已經(jīng)加過的元素就跳過 if(used[idx]){ continue; } // 加入該元素后繼續(xù)搜索 used[idx] = true; tmp.add(nums[idx]); helper(nums, tmp); tmp.remove(tmp.size()-1); used[idx] = false; // 跳過本輪的重復(fù)元素,確保每一輪只會加unique的數(shù)字 while(idx < nums.length - 1 && nums[idx] == nums[idx + 1]){ idx++; } } } } }
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/64532.html
摘要:題目詳情題目要求輸入一個可能會有重復(fù)數(shù)字的數(shù)組,要求我們輸出可能組成的全排列無重復(fù)排列。可以用來實現(xiàn),但這種實現(xiàn)方式復(fù)雜度高。另外一種實現(xiàn)思路是,新聲明一個數(shù)組來存儲中元素的使用狀況。以這個數(shù)組為例。 題目詳情 Given a collection of numbers that might contain duplicates, return all possible unique ...
摘要:找規(guī)律復(fù)雜度時間空間思路由于我們只要得到第個全排列,而不是所有全排列,我們不一定要將所有可能都搜索一遍。根據(jù)全排列順序的性質(zhì),我們可以總結(jié)出一個規(guī)律假設(shè)全排列有個數(shù)組成,則第個全排列的第一位是。然后將得到,這個就是下一輪的。 Permutation Sequence The set [1,2,3,…,n] contains a total of n! unique permutati...
摘要:例如有如下的全排列想法這道題是用回溯法的思想解決的。回溯法在包含問題的所有解的解空間樹中,按照深度優(yōu)先的策略,從根節(jié)點出發(fā)深度優(yōu)先搜索,搜索到某個點的時候,先判斷該節(jié)點是否包含問題的解,如果包含就繼續(xù)探索,否則就逐層向根節(jié)點回溯。 題目詳情 Given a collection of distinct numbers, return all possible permutations....
摘要:當(dāng)前的值如果已經(jīng)被使用過,則繼續(xù)判斷下一個數(shù)值。則當(dāng)?shù)谝粋€被添加進結(jié)果集時,可以繼續(xù)使用第二個作為元素添加進結(jié)果集從而生成。假設(shè)將表示為那么結(jié)果集中會確保永遠在數(shù)值的前面,從而避免了和的重復(fù)情況出現(xiàn)。 題目要求 Given a collection of numbers that might contain duplicates, return all possible unique ...
摘要:題目要求也就是得出所有可能的排列組合結(jié)果解題思路和代碼這題顯然采用遞歸的思路。在這里,我采用實現(xiàn)隊列,從隊列頭獲得上一組的結(jié)果,和當(dāng)前元素結(jié)合之后,將結(jié)果插入到隊尾。 題目要求 Given a collection of distinct numbers, return all possible permutations. For example, [1,2,3] have the ...
閱讀 2345·2021-11-11 16:54
閱讀 2596·2021-09-26 09:47
閱讀 3978·2021-09-08 09:36
閱讀 2727·2021-07-25 21:37
閱讀 927·2019-08-30 15:54
閱讀 2540·2019-08-30 14:22
閱讀 3245·2019-08-30 13:57
閱讀 2558·2019-08-29 17:17