46、全排列

会有一股神秘感。 提交于 2019-12-18 13:03:33

问题描述

在这里插入图片描述

问题分析

分析题目,这是一道经典的回溯法题目:

backtrack(res, nums, tmp, visited);

  • res是结果集
  • nums是候选集
  • tmp是当前路径
  • visit是访问控制集

基本算法思路是

backtrack(res, nums, tmp, visited){
	//回溯结束条件(一般是tmp长度符合条件)
	if(满足条件){
		res添加路径tmp;
		return;
	}

	//遍历候选集,继续递归
	for(候选集){
		//做选择(包括路径添加元素,和设置visit等)
		tmp+1;
		visit[i] = false;
		
		//继续递归(backtrack(res, nums, tmp, visited))
		backtrack(res, nums-1, tmp+1, visited)
		
		//撤销选择(包括路径删除元素,和取消设置visit等)
		tmp-1;
		visit[i] = true;
	}
}

解法:回溯法

  • 时间复杂度:指数或者阶乘。

Java代码

package com.company;

import java.util.ArrayList;
import java.util.List;

public class Main {

    public static void main(String[] args) {

        int[] a = {1, 2, 3};
        List<List<Integer>> result = permute(a);
        System.out.println(11);

    }

    static public List<List<Integer>> permute(int[] nums) {

        //回溯法截止步数
        int n = nums.length;
        //结果数组
        List<List<Integer>> result = new ArrayList<List<Integer>>();
        //访问控制数组
        boolean[] visited = new boolean[n];

        backtrack(result, nums, new ArrayList<Integer>(), visited);


        return result;

    }

    private static void backtrack(List<List<Integer>> result, int[] nums, ArrayList<Integer> temp, boolean[] visited) {
        if (temp.size() == nums.length){
            result.add(new ArrayList<>(temp));
            return;
        }

        for (int i = 0; i < nums.length; i++) {
            if (!visited[i]){
                //做选择
                visited[i] = true;
                temp.add(nums[i]);
                //回溯
                backtrack(result, nums, temp, visited);
                //撤销选择
                visited[i] = false;
                temp.remove((Integer) nums[i]);
            }
        }



    }


}

结果分析

以上代码的执行结果:

执行时间 内存消耗
2 ms 38.5 MB

在这里插入图片描述

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!