算法入门(回溯算法)
Posted 韶光不负
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法入门(回溯算法)相关的知识,希望对你有一定的参考价值。
当学习完递归后,就可以来学习与理解它好兄弟回溯了。回溯算法比较抽象,小编就以自己学习的角度来分析了!
回溯与递归有什么关系
递归与回溯是相辅相成的,回溯算法在递归之后,(可以理解没有递归就没有回溯,递归下不一定使用回溯算法,要根据问题)
什么是回溯算法
回溯算法是一个暴力的搜索算法。回溯就是一个递归的过程
按选优条件向前搜索,以达到目标。 但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术,而满足回溯条件的某个状态的点称为"回溯点"。
所有的回溯法可以抽象为一个树形结构
如下图二叉树
回溯算法模板
void backtracking(参数)
if (终⽌条件)
存放结果;
return;
for (选择:本层集合中元素(树中节点孩⼦的数量就是集合的⼤⼩))
处理节点;
backtracking(路径,选择列表); // 递归
回溯,撤销处理结果
回溯算法能解决的题目
数组(leetcode 39,40,216),切割(140),子集(78,90),组合(46,47),少数棋盘(如n皇后(51),n数组问题)
数组总和(leetcode)
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)
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皇后
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;
以上是关于算法入门(回溯算法)的主要内容,如果未能解决你的问题,请参考以下文章