【LeetCode】46 - 全排列

题目描述

给定一个没有重复数字的序列,返回其所有可能的全排列。

示例:

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

解题思路

回溯法

设置一个指针first表示当前正在处理的元素,n表示数组nums的长度。

  • 如果first == n表示此时的全排列已经完成,把此时的列表加入到结果列表
  • 对数组从索引firstn-1进行遍历
    • nums[first]nums[i]进行交换
    • 继续(递归地)进行交换处理,接下来backtrack(first + 1)
    • 得到一组全排列后,要将数组恢复成交换之前的样子,以免在获取下一组全排列的过程中出错

Java 实现

public List<List<Integer>> permute (int[] nums) {
    List<List<Integer>> ans = new ArrayList<>();
    ArrayList<Integer> curList = new ArrayList<>();
    for (int num : nums) {
        curList.add(num);
    }
    int n = nums.length;
    backtrack(0, curList, n, ans);

    return ans;
}

private void backtrack (int first, ArrayList<Integer> curList, int n, List<List<Integer>> ans) {
    if (first == n) {
        ans.add(new ArrayList<Integer>(curList));
    }

    for (int i = first; i < n; i++) {
        Collections.swap(curList, first, i);
        backtrack(first + 1, curList, n, ans);
        Collections.swap(curList, first, i); // 回溯,使数组回到原来的样子重新操作
    }

}

心得体会

这一题的回溯算法体现在:交换完获得一组全排列后,要及时将数组交换回去,保持原样给下一次交换操作使用。

猜你喜欢

转载自www.cnblogs.com/yuzhenzero/p/10302890.html