算法入门(回溯算法)

news/2024/7/20 21:59:33 标签: 算法, 动态规划, java, 深度优先

当学习完递归后,就可以来学习与理解它好兄弟回溯了。回溯算法比较抽象,小编就以自己学习的角度来分析了!

 

回溯与递归有什么关系 

递归与回溯是相辅相成的,回溯算法在递归之后,(可以理解没有递归就没有回溯,递归下不一定使用回溯算法,要根据问题)

什么是回溯算法

回溯算法是一个暴力的搜索算法回溯就是一个递归的过程

按选优条件向前搜索,以达到目标。 但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术,而满足回溯条件的某个状态的点称为"回溯点"。

所有的回溯法可以抽象为一个树形结构

如下图二叉树

回溯算法模板

java">void backtracking(参数) {
     if (终⽌条件) {
     存放结果;
     return;
     }
     for (选择:本层集合中元素(树中节点孩⼦的数量就是集合的⼤⼩)) {
           处理节点;
         backtracking(路径,选择列表); // 递归
         回溯,撤销处理结果
     }
}

回溯算法能解决的题目

数组(leetcode 39,40,216),切割(140),子集(78,90),组合(46,47),少数棋盘(如n皇后(51),n数组问题)

数组总和(leetcode)

java">class Solution {
    List<List<Integer>> list = new ArrayList<>();
    List<Integer> list1 = new ArrayList<>();
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        Arrays.sort(candidates);
        helper(candidates,0,target);
        return list;
    }
    public void helper(int[] cand , int start ,int target){
        int len = cand.length;
        if (target == 0){
            list.add(new ArrayList<Integer>(list1));
            return;
        }
        for (int i = start; i < len ; i++) {
            if (cand[i] > target) break;
            list1.add(cand[i]);
            helper(cand,i,target - cand[i]);
            list1.remove(list1.size()-1);
        }
    }
}

全排列(46)

java">class Solution {
    List<List<Integer>> res = new ArrayList<>();
    List<Integer> output = new ArrayList<>();
    public List<List<Integer>> permute(int[] nums) {
        for (int num : nums) {
            output.add(num);
        }

        int n = nums.length;
        backtrack(n, output, res, 0);
        return res;
    }
    public void backtrack(int n, List<Integer> output, List<List<Integer>> res, int first) {
        // 所有数都填完了
        if (first == n) {
            res.add(new ArrayList<Integer>(output));
        }
        for (int i = first; i < n; i++) {
            // 动态维护数组
            Collections.swap(output, first, i);
            // 继续递归填下一个数
            backtrack(n, output, res, first + 1);
            // 撤销操作
            Collections.swap(output, first, i);
        }
    }
}

n皇后

java">package com.itheima;


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

class Solution {
    
    int[] arr;
    List<List<String>> res = new ArrayList<>();
    public List<List<String>> solveNQueens(int n) {
        arr = new int[n];
        dnf(n,0);
        return res;
    }
    public void dnf(int n , int index){
        if (n == index){
            ArrayList<String> list = new ArrayList<>();
            for (int i = 0; i < n;i++){
                StringBuilder str =new StringBuilder();
                for (int j = 0; j < n ; j++) {
                    if (arr[i] == j){
                        str.append('Q');

                    }else {
                        str.append('.');
                    }
                }
                list.add(new String(str));
            }
            res.add(list);
            return;
        } else{
            for (int i = 0; i < n ; i++) {
                arr[index] = i;
                if (judge(index)){
                    dnf(n,index+1);
                }
            }
        }

    }
    private boolean judge(int index) {
        for (int i = 0; i < index; i++) {
            if (arr[i] == arr[index] || Math.abs(i - index) == Math.abs(arr[i] - arr[index])) {
                return false;
            }
        }
        return true;
    }
}


http://www.niftyadmin.cn/n/1832699.html

相关文章

Java操作数据库(二,SQL注入与PreparedStatement)

JDBC入门https://blog.csdn.net/weixin_47514459/article/details/121719450 小编相信&#xff0c;通过对上文的阅读&#xff0c;让各位对jdbc&#xff08;Java对数据库的操作&#xff09;已经有一定的认识&#xff0c;下面我们就来看看SQL注入的问题与PreparedStatement&#…

NEU 1009 Happiness Hotel

1009: Happiness Hotel 时间限制: 1 Sec 内存限制: 128 MB提交: 173 解决: 19[提交][状态][讨论版]题目描述 The life of Little A is good, and, he managed to get enough money to run a hotel. The best for him is that he need not go to work outside, just wait for …

慢慢学习,然后惊呆所有人(构造器,this关键字)

此篇文章是对自己一个Java专题的内容进行补充&#xff0c;欢迎大家观看与评论小编的博客&#xff0c;如果喜欢小编的博客也不要忘了关注与收藏哦&#xff01; 目录 new到底对对象做了什么&#xff1f; 创建对象的过程 构造器(一般在类属性下) 无参构造 this关键字 this永远…

【一】Jmeter接口自动化测试系列之参数化方法

Jmeter作为虽然作为一款和LoadRunner相媲美的性能测试工具&#xff0c;但参数化功能实在不咋地&#xff0c;这里我大概总结了一下Jmeter的参数化方法&#xff01; 至于参数化的用途&#xff0c;我这里就不多说了&#xff0c;做测试的都明白吧&#xff01;本文主要介绍最全、最…

Java操作数据库(三,趣味理解JDBC事务)

如果读者对此篇文章有不解可以查看小编JDBC分区下的文章哦&#xff0c;欢迎大家点赞与收藏&#xff01; 目录 事务 事务的讲解小编准备从一个故事进行讲起&#xff1a; 创建一个银行&#xff08;数据库创建&#xff0c;张三&#xff1a;100000&#xff0c;小明&#xff1a;0&…

Linux 安装oracle

具体过程如下&#xff1a;1 - 确认如下安装包&#xff0c;若没有安装&#xff0c;则从光盘中找到相应的包进行安装#rpm -qa | grep binutils binutils-2.17.50.0.6-2.el5compat-libstdc-33-3.2.3-61elfutils-libelf-0.125-3.el5elfutils-libelf-devel-0.125glibc-2.5-12glibc-c…

电路板排列0032算法笔记——电路板排列问题和连续邮资问题回溯法求解

每日一贴,今天的内容关键字为电路板排列 1、电路板排列问题 问题描述 将n块电路板以佳最排列式方入插带有n个插槽的机箱中。n块电路板的不同排列式方对应于不同的电路板入插案方。设B{1, 2, …, n}是n块电路板的集合&#xff0c;L{N1, N2, …, Nm}是接连这n块电路板中多少电路板…

codebook法分割前景目标

利用codebook法训练得到背景模型后&#xff0c;对背景差分得到的掩模图像去噪声并找到较大连通域。相对于平均背景法&#xff0c;它的分割效果更好些。当然&#xff0c;分割效果和背景模型训练的帧数有很大关系&#xff0c;适当调整一些参数会得到更好的效果。 1 #include &quo…