![](https://img-blog.csdnimg.cn/20201014180756922.png?x-oss-process=image/resize,m_fixed,h_224,w_224)
回溯
贪心
爱抖腿的嘻嘻嘻
这个作者很懒,什么都没留下…
展开
-
DFS--矩阵中的最长递增路径(深搜+记忆化)
普通dfs找到一个数组中的最长的路径第一个想法是dfs,深度遍历回溯每一个格子的上下左右格子,更新最长路径,遍历完所有的则遍历完成遍历的途中就是dfs(i,j,x)i,j分别是此时矩阵的坐标,数组可以创建一个外部数组这样就不用每次传数组了,然后进入dfs,首先进行判断是否越界,越界则返回,然后进行四次dfs,这个dfs的过程中在外界定义一个dir双层数组,里面包含{1,0},{0,1},{-1,0},{0,-1}四个数组,这样就可以在dfs时通过for循环四次。每次x和y都加这个数组中的值来直接得到原创 2021-01-09 21:58:58 · 367 阅读 · 0 评论 -
组合1.无重复元素
利用begin结束条件为满足条件就这class Solution { List<List<Integer>> res =new ArrayList<List<Integer>>(); public List<List<Integer>> combinationSum(int[] candidates, int target) { if(candidates.length==0){原创 2021-04-02 01:48:07 · 104 阅读 · 0 评论 -
回溯问题总结--一道笔试题的折磨加顿悟
今天是2021.4.2日,笔试携程的一道题的时候出现大问题,明明思路是对的,就是过不了,于是不开心了一天,一直在思考是哪里的问题,现在忽然发现哦,茅塞顿开,按照这个思路来做,再有回溯的题不会我是猪。回溯主要用来在一颗解空间树上求哪种拥有想要的效果。其实就是解决子序列问题的,子序列问题的暴力解就是回溯。在一排列组合的大树中,要哪个元素不要哪个元素,其实总结起来就很简单,三种情况。一定要画出解空间树的图来,才能确定怎么来回溯。排列第一种是排列,也就是所有的元素都得要,只不过排的顺序不同,它用的方法是原创 2021-04-02 01:41:07 · 115 阅读 · 0 评论 -
组合4.1到9中和为n的k个数的组合
画出解空间树,可以发现是一个组合问题,而且递归中不能重复之前的数。所以用begin,传入i+1当递归的begin。结束就利用target就可以判断。class Solution { List<List<Integer>> res=new ArrayList<List<Integer>>(); public List<List<Integer>> combinationSum3(int k, int n) {原创 2021-03-26 22:07:06 · 109 阅读 · 0 评论 -
组合3.组合77
组合,画出图来就可以确定。关键是它的元素在一次递归中不能重复,所以传入i+1.class Solution { List<List<Integer>> res=new ArrayList<List<Integer>>(); public List<List<Integer>> combine(int n, int k) { if(n==0 || k>n){ return原创 2021-03-26 21:52:18 · 93 阅读 · 0 评论 -
组合2.有重复元素
有重复元素的话就不能再递归中重复选择了。画出解空间图,可以发现在选择列表中仍然需要跳过重复元素,所以需要排序,而且因为是组合,所以选择列表的起点仍然应该是begin。那怎么避免在递归中跳过重复元素呢,在组合中利用的是used数组,如果发现没有使用过,说明跳出了上次的递归,这次可以使用了。而组合利用的是begin来限制选择列表中可以选择的元素,在递归中反而可以用,因为要把此时的i传进去来当递归的begin,所以递归可选择的范围是更大的,但是在这个题中,一个数字也不能选多次,所以应该传入的是i+1所以如果此原创 2021-03-26 21:35:55 · 177 阅读 · 0 评论 -
排列2.有重复数字
全排列(有重复数字)和无重复数字时候一样,画出解空间树,发现这种在遍历的时候仍然是一样的,只不过列表空间在发现重复的时候需要跳过,怎么发现重复呢,可以进行排序,然后和前一个比就可以。但是它递归路径中是不用跳过的,所以判断是否跳过时候就需要判断这个是在进行列表的迭代还是递归。一个很巧妙的方法就是看used数组,如果此时前一个值是false,说明已经递归完了,这个是遍历,就可以跳过。如果不是,则不跳过。class Solution { List<List<Integer>>原创 2021-03-26 21:01:27 · 247 阅读 · 0 评论 -
游戏1.n皇后问题
nn的矩阵,需要每次选n个选择,选择n次,就是一个数每次都可以使用的全排列问题,但其实不是每次都需要选n次,而是要根据以前的选择来决定现在可以选什么。只是限制条件比一般的全排列问题更多。所以先将一个nn的char表赋值为.,然后开始从第一行开始选,就是for循环这个数组,如果这个点符合标准,则递归开始选下一行,否则就跳过。如果最终发现遍历完最后一行,则将这个表加入res中继续回溯遍历。检查这个值是否冲突,则需要检查这个值的上方列,左上方,右上方。class Solution { List<原创 2021-02-02 10:58:47 · 73 阅读 · 0 评论 -
排列5.字母大小写全排列
可以用回溯来做,不过就两种 情况,把目前在遍历的字母变成大写或者不变大写两种,所以不用for循环class Solution { List<String> res=new ArrayList<String>(); public List<String> letterCasePermutation(String S) { if(S.length()==0)return res; core(S.toCharArray(),原创 2021-01-31 22:37:43 · 368 阅读 · 0 评论 -
组合5.电话号码的字母组合
可以从中看到这个是类似于组合的,比如给的数字是234,则可以选一个数字,从2开始选字母,则3选的时候就不能选2了。所以理应用begin来限制下次选的时候选的2中选过的字母,但这个题比较特殊的是他们的数组是分开的,也就是向下递归到3时也应该从0开始,所以就不用begin。class Solution { List<String> res=new ArrayList<String>(); public List<String> letterCombinati原创 2021-01-31 21:51:14 · 100 阅读 · 0 评论 -
排列4.括号生成(特殊条件的排列)
根据题目可以画出回溯树,非常直观,需要处理的就是何时回溯,结束递归条件是此时长度达到规定长度。如果此时左括号数量小于n,则继续添加左括号。如果左括号数量大于右括号,则添加右括号。class Solution { List<String> res=new ArrayList<String>(); public List<String> generateParenthesis(int n) { if(n==0)return res;原创 2021-01-28 10:50:34 · 329 阅读 · 0 评论 -
组合5.子集
子集是一个组合问题,单支需要剪枝,各个分支之间也需要剪枝。而且每次加入值都需要放入res中。class Solution { List<List<Integer>> res=new ArrayList<List<Integer>>(); public List<List<Integer>> subsets(int[] nums) { if(nums==null || nums.length==0){原创 2021-01-07 21:30:50 · 151 阅读 · 0 评论 -
排列3.返回全排列中的第k个序列
返回第k个序列,序列是共有n个元素的集合中的全排列首先这是一个排列问题,用used,然后序列中没有重复的元素,只是对集合进行排列而已,当进行到第k个时候直接返回即可。class Solution { String res=""; int count=1; public String getPermutation(int n, int k) { boolean[] used=new boolean[n]; StringBuffer buffer =原创 2021-01-03 00:51:43 · 342 阅读 · 0 评论 -
排列1.无重复数字
import java.util.ArrayList;import java.util.Stack;class Solution { List<List<Integer>> res =new ArrayList<List<Integer>>(); public List<List<Integer>> combinationSum(int[] candidates, int target) { if(c原创 2020-12-27 22:24:33 · 130 阅读 · 0 评论