回溯算法oj

简单回溯算法oj

回溯算法先画树形图!!!!!

以下三类题模板基本一样,不同之处只是剪枝的方法。回溯算法剪枝要画出树形图,这样就很清楚哪一步该剪枝,依据其特点剪枝。

模板:

void backtrack(parameters) {
   
    if(满足条件){
   
        //get one answer
        record answer;
        return;
    }
    
    for(解空间树的下一个节点){
   
        backtrack(paramter);
    }
}

1、全排列

leetcode-46 全排列

思路:用一个数组来存储已经搜索过的数据,当遍历的起始位置等于数组长度时,说明找到一个排列。添加到结果集并return

public class permutations {
   
    List<List<Integer>> res = new ArrayList<>();
    public List<List<Integer>> permute(int[] nums) {
   
		//因为回溯算法最后会还原上一步操作,用原数组来存储每一次的结果
        dfs(nums,0,nums.length - 1);    
        return res;
    }

    public void dfs(int[] nums,int start,int end) {
   
        if(start == end) {
     //说明已经走到nums的末尾,找到一个结果
            List<Integer> temp = new ArrayList<>();
            for(int i = 0; i < nums.length;i++) {
   
                temp.add(nums[i]);
            }
            res.add(temp);
            return;
        }

        //回溯+递归
        for(int i = start; i <= end;i++) {
   
            swap(nums,start,i);    //每次交换元素,可以得到两个元素的全排列
            //求剩下元素的全排列,如果可以一直递归下去找到结果,那么就会添加结果到结果集中
            dfs(nums,start + 1,end);
            //不论有没有找到,上面递归跳出后,都会再次交换,将原本交换的两个元素恢复
            //即回溯,恢复现场
            swap(nums,start,i);
        }
    }

    public void swap(int[] nums,int i,int j) {
   
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
}

dfs函数的第三个参数没有必要,可以通过原数组计算出来

    List<List<Integer>> ans = new ArrayList<>();
    public List<List<Integer>> permute(int[] nums) {
   
        if(nums.length == 0) return ans;
        dfs(0,nums);  //不用传数组长度,因为本身传入的数组就是原数组,直接可以计算长度
        return ans;
    }

    public void dfs(int n,int[] array)  {
   
        if(n == array.length) {
      //找到一个解
        List<Integer> tmp = new ArrayList<>();
        for(int i : array) {
   
            tmp.add(i);
        }
        ans.add(tmp);
        return;
        }

        for(int i = n; i < array.length;i++) {
   
            swap(n,i,array)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值