Leetcode——46全排列、47全排列2(回溯法)

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

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

示例:

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

【思路】
拿到這個題第一反應就是回溯法,要搞清回溯法具體的過程,我們可以通過畫一個樹形圖來理解。需要分析清楚題目的是,對於該排列問題,只要我們按照順序選取數組,最主要的是上一層出現的數字,下一層不能再出現。
在這裏插入圖片描述
注意:

1、在每一層,我們都有若干條分支供我們選擇。由於是排序問題,之前使用過的數字,在下一層中不能再選取,那麼從當前層走到下一層的時候,我們就要問一問自己,哪些數字已經使用過。在編碼實現中,可以使用一個布爾型數組 used,用於記錄之前哪些數字使用過。

2、在程序執行到上面這棵樹的葉子結點的時候,此時遞歸到底,方法要返回了,對於這個最後一層選取的數,要做兩件事情:(1)釋放對它的佔用;(2)將它從當前選取放進的排列中彈出。當前,在每一層的方法執行完畢,要返回的時候,都需要這麼做。這兩點可以簡單概括爲“狀態重置”。

參考鏈接:https://leetcode-cn.com/problems/two-sum/solution/hui-su-suan-fa-python-dai-ma-java-dai-ma-by-liweiw/
【實現代碼】

class Solution {
    public List<List<Integer>> permute(int[] nums) {
        int len=nums.length;
        List<List<Integer>> res=new ArrayList<>();
        boolean[] used=new boolean[len];
        if(len==0) return res;
        generatePermution(nums,used,0,len,new Stack<>(),res);
        return res;
    }
    
    private void generatePermution(int[] nums,boolean[] visited,int curSize,int len,Stack<Integer> path,List<List<Integer>> res){
        if(curSize==len){
            //此時path已經保存了nums中所有數字已經成爲一個排列
            res.add(new ArrayList<>(path));
            return;
        }
        for(int i=0;i<len;i++){
            if(!visited[i]){
                path.push(nums[i]);
                visited[i]=true;
                generatePermution(nums,visited,curSize+1,len,path,res);
                path.pop();
                visited[i]=false;
            }
        }
    }
    
}

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

示例:

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

【思路】
感覺和未重複的程序大體差別沒有很大,現在就是需要判斷重複的數字如何進行處理。首先對數組進行排序,排序之後。在進入一個新的分支之前,看一看這個數是不是和之前的數一樣,如果這個數和之前的數一樣,並且之前的數還未使用過,那接下來如果走這個分支,就會使用到之前那個和當前一樣的數,就會發生重複,此時分支和之前的分支一模一樣。(因爲前一個數之前已經走過了,所以未使用的話接下來要走的分支就和之前的一樣。)
參考鏈接:https://leetcode-cn.com/problems/two-sum/solution/hui-su-suan-fa-python-dai-ma-java-dai-ma-by-liwe-2/
來源:力扣(LeetCode)
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。
在這裏插入圖片描述在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
【實現代碼】

package array;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Stack;

public class Permution {

	
	
	
	public static void main(String[] args){
		int[] nums=new int[]{1,1,2};
        List<List<Integer>> res=new ArrayList<>();
        res=permuteUnique(nums);
        for(int i=0;i<res.size();i++){
        	System.out.println(res.get(i));
        }
	}

	private static List<List<Integer>> permuteUnique(int[] nums) {
		 int len=nums.length;
	        List<List<Integer>> res=new ArrayList<>();
	        boolean[] used=new boolean[len];
	        if(len==0) return res;
	        Arrays.sort(nums);
	        findPermution(nums,used,0,len,new Stack<>(),res);
	        return res;
	}

	private static void findPermution(int[] nums, boolean[] used, int depth, int len, Stack<Integer> stack,
			List<List<Integer>> res) {
		// TODO Auto-generated method stub
		if(depth==len){
			res.add(new ArrayList<Integer>(stack));
			return;
		}
		for(int i=0;i<len;i++){
			if(!used[i]){
				if(i>0&&nums[i]==nums[i-1]&&!used[i-1]){
					continue;
				}
				used[i]=true;
				stack.add(nums[i]);
				findPermution(nums, used, depth+1, len, stack, res);
				stack.pop();
				used[i]=false;
			}
		}
		
	}

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章