题解 | #没有重复项数字的全排列#

没有重复项数字的全排列

https://www.nowcoder.com/practice/4bcf3081067a4d028f95acee3ddcd2b1

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param num int整型一维数组
     * @return int整型ArrayList<ArrayList<>>
     */
    public ArrayList<ArrayList<Integer>> permute (int[] num) {
        // write code here
        // 左程云老师讲过全排列的分支限界递归法解决不重复全排列问题
        // 调用一个递归函数,这个递归函数负责对当前i位置的数字进行与i ~ num.length - 1中的位置依次互换,然后继续考察i + 1处的情况

        // 算法的时间复杂度0(N!),额外空间复杂度0(N!)

        // 用于记录所有路径的结果
        ArrayList<ArrayList<Integer>> finalResults = new ArrayList<>();

        // 调用这个递归函数,从num数组的0位置开始,将每一次找到的oneResult填进finalResult中
        process(num, finalResults, 0);

        // 返回最终的答案finalResults
        return finalResults;
    }

    public void process(int[] num, ArrayList<ArrayList<Integer>> finalResults, int i) {
        // 递归出口(底部)
        if (i == num.length) {
            // i越界了,说明整个数组遍历完毕了,将单个路径上的答案oneResult写入总答案finalResults中
            // 踩坑点1:这里一定要【现场新创建】一个ArrayList放入答案中,如果提前在主方法创建好,那么随着每次递归的调用,finalResults里面的值也会被修改
            ArrayList<Integer> oneResult = new ArrayList<>();
            for (Integer n : num) {
                oneResult.add(n);
            }
            finalResults.add(oneResult);
        }

        // 递归分支
        for (int j = i; j < num.length; j++) {
            // 将num[j]算入这次的结果中
            swap(num, i, j);
            // 在算入num[j]的基础上继续考察num数组中i+1往后的位置
            process(num, finalResults, i + 1);
            // 注意!恢复现场,继续尝试将将num[j+1]算入这次的结果中
            // 踩坑点2:一定要【恢复现场】,要不然无法准确列出要分支的情况
            swap(num, j, i);
        }
    }

    // 数组元素交换函数
    public void swap(int[] num, int i, int j) {
        if (i == j) {
            return;
        }
        int t = num[i];
        num[i] = num[j];
        num[j] = t;
    }
}

全部评论

相关推荐

迟缓的斜杠青年巴比Q...:简历被投过的公司卖出去了,我前两天遇到过更离谱的,打电话来问我有没有意向报班学Java学习,服了,还拿我学校一个学长在他们那报班学了之后干了华为OD当招牌
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务