leetCode46:全排列

题目:

给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。

示例 1:

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

思路:

  • 回溯法
  • Collections.swap 这一个工具方法,别写错了。

代码:

    public List<List<Integer>> permute(int[] nums) {
        List<List<Integer>> resultList = new ArrayList<>();
        if (nums==null) {
            return resultList;
        }
        //记录下所有要排列的数字
        List<Integer> numList = new ArrayList<>();
        for (int num: nums) {
            numList.add(num);
        }

        int length = nums.length;
        //排列
        backTrack( length, resultList, numList, 0);
        
        return resultList;
    }


    public void backTrack( int length, List<List<Integer>> resultList, List<Integer> numList, int num) {
        //如果已经排列完了,就添加到结果集中
        if (length == num) {
            resultList.add ( new ArrayList<>(numList));
        }

        // [0,1 ∣ 2,3,4] ,左边的是填过的数,右边的是没有填的数。
        // 假设待填的数的下标为 i,那么填完以后我们将第 i 个数和第 num 个数交换,
        // 使得在填第 num+1 个数的时候 nums 数组的 [0,num] 部分为已填过的数,[num+1, length−1] 为待填的数。

        // 易错点:这里的循环,从 num  开始的。别写错了。
        for (int i=num ; i < length; i++) {
            //将numList划分成左右两个部分,左边的表示已经填过的数,右边表示待填的数,
            //交换,表示 i 已经填过
            //Collections.swap 这一个工具方法,别写错了。
            Collections.swap ( numList, num, i);
            //循环,选择后续数据
            backTrack( length, resultList, numList, num+1);
            //撤销交换。回溯的时候交换回来即能完成撤销操作
            Collections.swap ( numList, num, i );

        }

    }

posted on 2025-02-19 18:22  乐之者v  阅读(17)  评论(0)    收藏  举报

导航