1. 程式人生 > 其它 >46. 全排列(java實現)--LeetCode

46. 全排列(java實現)--LeetCode

技術標籤:演算法題遞迴算髮題leetcode演算法資料結構java

文章目錄

題目:

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

示例:

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

解法1:遞迴(換位)

/**
 * 思路:
 * 放格子,第一個格子放所有的數
 * 第二個放除第一個格子外所有的數
 * 第三個格子放除1,2格子中的所有的數
 * 。。。
 * 最後就是所有的可能性
 *
 * 為了實現上面的效果
 * 我們把nums所有的數存入list,之後在其每個位置(格子)上進行交換
 * 先和自身換,之後和後面所有的數進行交換。這樣第一個格子就儲存了所有的數
 * 對於後面的格子用遞迴,進行同樣的操作
 * 最後要把變換後的數換回來,以便下次遞迴不重複
 */
public List<List<Integer>> permute(int[] nums) { ArrayList<List<Integer>> result = new ArrayList<>(); ArrayList<Integer> list = new ArrayList<>(); for (int num:nums)list.add(num); backtrack(nums.length,0,list,result); return
result; } private void backtrack(int length, int lattice, ArrayList<Integer> list, ArrayList<List<Integer>> result) { if (lattice==length) { result.add(new ArrayList<>(list)); return; } for (int i=lattice;i<length;i++
){ Collections.swap(list,lattice,i); backtrack(length,lattice+1,list,result); Collections.swap(list,lattice,i); } }

時間複雜度:On^2

空間複雜度:On
在這裡插入圖片描述

解法2:

/**
 * 和解法1的思路一樣,不過這裡借用了set
 * 思路:
 * 往格子裡放數,當前格子的數需要遍歷陣列,並且不能是之前放過的
 * 因為沒有從重複數字用set來存放之前放過的數。
 * 每次遞迴結束就從set和list中移除這個數
 */
     public List<List<Integer>> permute(int[] nums) {
        ArrayList<List<Integer>> result = new ArrayList<>();
        LinkedList<Integer> list = new LinkedList<>();
        HashSet<Integer> set = new HashSet<>();
        recursive(nums,0,result,list,set);
        return result;
    }

    private void recursive(int[] nums, int lattice, ArrayList<List<Integer>> result, LinkedList<Integer> list, HashSet<Integer> set) {
        if (lattice==nums.length){
            result.add(new ArrayList<>(list));
            return;
        }
        for (int i:nums){
            if (set.add(i)){
                list.add(i);
                recursive(nums,lattice+1,result,list,set);
                list.removeLast();
                set.remove(i);
            }
        }
    }

時間複雜度:On^2

空間複雜度:On
在這裡插入圖片描述