代码随想录之回溯(力扣题号)
创始人
2025-05-30 18:26:39
0

77 组合

在这里插入图片描述
改了非常非常非常久!!不知道为什么用set去重就是没成功。在遍历的时候剪枝感觉没那么容易想到

class Solution {ArrayList> res = new ArrayList>();ArrayList num = new ArrayList();public List> combine(int n, int k) {//21dfs(n,1,k);return res;}public void dfs(int n,int index,int k){if(num.size()==k){//长度够了res.add(new ArrayList<>(num));return;}for(int i=index;i<=n;i++){if(num.contains(i)) continue;num.add(i);dfs(n,i+1,k);//注意不是index+1 下一轮搜索,设置的搜索起点要加 1,因为组合数理不允许出现重复的元素//这样后面的元素一定比之前的元素来得大!!!!num.remove(num.size()-1);}}
}

216 组合总和3

在这里插入图片描述
一开始看成是三数之和,后来发现可以是任意k个数量,所以还是用回溯
没想到还是一次过了

class Solution {ArrayList> res = new ArrayList>();List num = new ArrayList<>();public List> combinationSum3(int k, int n) {//44-52 三数之和 但是是k个数!!52-00dfs(1,k,n,0);return res;}public void dfs(int count,int k,int n,int sum){if(sum>n) return;//减枝if(num.size()==k&&sum==n){res.add(new ArrayList<>(num));return;}for(int i=count;i<=9;i++){num.add(i);dfs(i+1,k,n,sum+i);num.remove(num.size()-1);}}
}

时间复杂度好高

17 电话号码的字母组合

在这里插入图片描述
一开始对映射无从下手,还在找字母和数字之间的规律,看了题解发现可以用String[]数组存,用对应数字做下标就可以方便找到。然后就是回溯的常规写法了,就是对应数字的遍历要仔细一些

class Solution {List res = new ArrayList<>();StringBuilder tmp = new StringBuilder();public List letterCombinations(String digits) {//30-54if(digits.length()==0) return res;String[] map = {"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};dfs(map,digits,0);return res;}public void dfs(String[] map, String s, int index){if(tmp.length()==s.length()){res.add(new String(tmp.toString()));return;}for(int i=0;itmp.append(map[s.charAt(index)-'0'].charAt(i));dfs(map,s,index+1);tmp.deleteCharAt(tmp.length()-1);}}
}

39 组合总和

在这里插入图片描述

class Solution {ArrayList> res = new ArrayList>();List tmp = new ArrayList();public List> combinationSum(int[] candidates, int target) {//26-37Arrays.sort(candidates);dfs(candidates,target,0);return res;}public void dfs(int[] candidates, int target,int index){if(target==0){res.add(new ArrayList(tmp));return;}for(int i=index;iif(candidates[i]>target) break;tmp.add(candidates[i]);dfs(candidates,target-candidates[i],i);//注意是i 这样可以重复使用,并且后面的都不会比之前小,不需要排序再去重tmp.remove(tmp.size()-1);}}
}

40 组合总和2

在这里插入图片描述

class Solution {ArrayList> res = new ArrayList>();List tmp = new ArrayList();public List> combinationSum2(int[] candidates, int target) {//10Arrays.sort(candidates);// List dfs(candidates,target,0);return res;}public void dfs(int[] candidates, int target, int index){if(target==0){res.add(new ArrayList(tmp));return;}for(int i=index;iif(candidates[i]>target) break;//要对同一树层使用过的元素进行跳过if(i>index&&candidates[i-1]==candidates[i]) continue;//一开始写的是//if(i>0&&candidates[i-1]==candidates[i]&&!tmp.contains(candidates[i-1])) continue;tmp.add(candidates[i]);dfs(candidates,target-candidates[i],i+1);tmp.remove(tmp.size()-1);}}
}

debug了很久!!我原来的判断方式也就是注释掉的那行思路是没问题,问题在于contains函数的判断
[2,2,2] target=4这样的例子就会出来两个[2,2].因为contains判断的是值的内容!!也就是第几个2在里面都会判断出包含,而我希望不同索引的2是有区别的,所以要这样判断就要用索引去判断!!还是用答案中的方法更简洁!!!

 //要对同一树层使用过的元素进行跳过if(i>index&&candidates[i-1]==candidates[i]) continue;

131 分割回文串

在这里插入图片描述
感觉这题没有太简单,代码独立完成之后测试出现了问题,比如会出现b这样的答案,手动debug才改了过来(注释掉的for循环),要是有这个循环,i就有可能从中间开始,答案就不连续,改完bug总共花了半个小时,还是需要再练习

class Solution {ArrayList> res = new ArrayList>();List tmp = new ArrayList();public List> partition(String s) {//37-08dfs(s,0);return res;}public void dfs(String s, int index){if(index==s.length()){res.add(new ArrayList(tmp));return;}//  for(int i = index;i//可以遍历的长度int i = index;for(int j=1;j<=s.length()-i;j++){if(isH(s.substring(i,i+j))){tmp.add(s.substring(i,i+j));dfs(s,i+j);tmp.remove(tmp.size()-1);}}// }}//判断是否是回文串public boolean isH(String s){char[] c = s.toCharArray();for(int i=0,j=c.length-1;i<=j;i++,j--){if(c[i]!=c[j]) return false;}return true;}}

改一下用通用的写法

class Solution {ArrayList> res = new ArrayList>();List tmp = new ArrayList();public List> partition(String s) {//37-08dfs(s,0);return res;}public void dfs(String s, int index){if(index==s.length()){res.add(new ArrayList(tmp));return;}for(int i = index;iif(isH(s.substring(index,i+1))){tmp.add(s.substring(index,i+1));dfs(s,i+1);tmp.remove(tmp.size()-1);}}}public boolean isH(String s){char[] c = s.toCharArray();for(int i=0,j=c.length-1;i<=j;i++,j--){if(c[i]!=c[j]) return false;}return true;}}

93 复原ip地址

在这里插入图片描述
这题写了很久没写出来!!要重点关注

class Solution {List res = new ArrayList();StringBuilder tmp = new StringBuilder();public List restoreIpAddresses(String s) {//21dfs(s,0,0);return res;}public void dfs(String s, int index, int num){//总共4段if(index==s.length()&&num==4){res.add(new String(tmp));return;}if(index==s.length()||num==4) return; //点过多或过少都不行for(int i=index;i //从index开始,最多3位int data = Integer.parseInt(s.substring(index,i+1));if(data>255||data<0) break;//数据范围不对直接返回if(i-index>0&&s.charAt(index)=='0') continue;//第一位为0并且这段长度>1tmp.append(s.substring(index,i+1));if(num<3) tmp.append(".");//最后一段不用加点dfs(s,i+1,num+1);     tmp.delete(index + num, tmp.length());//i + number + 2//tmp.delete(tmp.length()-i-2+index,tmp.length());        }}
}

78 子集

在这里插入图片描述
这题写得比较快,也不需要减枝

class Solution {ArrayList> res = new ArrayList>();List tmp = new ArrayList();public List> subsets(int[] nums) {//03-13for(int i=0;i<=nums.length;i++){//有几位dfs(nums,0,i);     }return res;}public void dfs(int[] nums, int index, int num){if(tmp.size()==num){res.add(new ArrayList(tmp));return;}for(int i=index;itmp.add(nums[i]);dfs(nums,i+1,num);tmp.remove(tmp.size()-1);}}
}

90 子集2

在这里插入图片描述
就是结合了79子集和20组合总和2,加个树层去重即可

class Solution {ArrayList> res = new ArrayList>();List tmp = new ArrayList();public List> subsetsWithDup(int[] nums) {//40-46Arrays.sort(nums);for(int i=0;i<=nums.length;i++){dfs(nums,0,i);}return res;}public void dfs(int[] nums, int index, int num){if(tmp.size()==num){res.add(new ArrayList(tmp));return;}for(int i=index;iif(i>index&&nums[i-1]==nums[i]) continue;tmp.add(nums[i]);dfs(nums,i+1,num);tmp.remove(tmp.size()-1);}}
}

491 递增子序列

在这里插入图片描述

剪枝没想出来!!这题不能排序!!可以利用标记数组

class Solution {ArrayList> res = new ArrayList>();List tmp = new ArrayList();public List> findSubsequences(int[] nums) {//49// Arrays.sort(nums);dfs(nums,0);return res;}public void dfs(int[] nums, int index){if(tmp.size()>1)res.add(new ArrayList(tmp));// 注意这里不要加return,要取树上的节点int[] used = new int[201];//nums[i]+100  定义在dfs内同一层就会公用一个used数组,下层used数组又清零,所以实现了数层减枝,而树叶不减Arrays.fill(used,0);for(int i=index;i//if(i>index&&nums[i-1]==nums[i]) continue;if(used[nums[i] + 100] == 1) continue;if(tmp.size()==0||(tmp.size()>0&&nums[i]>=tmp.get(tmp.size()-1))){used[nums[i] + 100] = 1;tmp.add(nums[i]);dfs(nums,i+1);tmp.remove(tmp.size()-1);}}}
}

47 有重复数字的全排列


不用set去重,直接剪枝,数组标记每个位置的数字是否被使用过而不是统计每个数字出现的次数,这样在剪枝判断的时候就可以利用上一个相同的数字是否出现过来判断。

class Solution {ArrayList> res = new ArrayList>();List tmp = new ArrayList();int[] count = new int[10];public List> permuteUnique(int[] nums) {//59-16Arrays.sort(nums);for(int i=0;icount[i]=1;}dfs(nums,0);return res;}public void dfs(int[] nums, int index){if(index==nums.length){res.add(new ArrayList(tmp));return;}for(int i=0;iif(i>0&&nums[i-1]==nums[i]&&count[i-1]==1) continue;if(count[i]<=0) continue;tmp.add(nums[i]);count[i]=0;dfs(nums,index+1);tmp.remove(tmp.size()-1);count[i]=1;}}
}

332 重新安排行程

在这里插入图片描述

没看题解真的想不到和回溯有什么关系,还是看了别人的代码再自己手打的,还是从这个代码中学到了不少,compareTo函数可以用来比较String的大小,写法和其他回溯没有什么区别,就是多用来判断如果找到了结果就返回,不用继续往下,因为先对tickets排序过了,先找到的一定是符合要求的字典序最小的,所以找到了就不用再找了

class Solution {List res = new ArrayList();List path = new ArrayList();boolean used[] = new boolean[301];public List findItinerary(List> tickets) {//17Collections.sort(tickets,(a,b)->a.get(1).compareTo(b.get(1)));//compareTo函数是对string的比较?//第一个本来就是要匹配的,所以只要比较第二个Arrays.fill(used,false);path.add("JFK");dfs(tickets);return res;}public boolean dfs(List> tickets){if(path.size()==tickets.size()+1){res = new ArrayList(path);return true;}for(int i=0;iif(!used[i]&&path.get(path.size()-1).equals(tickets.get(i).get(0))){path.add(tickets.get(i).get(1));used[i] = true;if(dfs(tickets)) return true;//找到了就不用再找path.remove(path.size()-1);used[i] = false;}}return false;        }
}

51 N皇后

在这里插入图片描述
这个写法是最简洁的,特别是判断是否合法的函数,第二次写还是写错了

class Solution {ArrayList> res = new ArrayList>();List tmp = new ArrayList();int[] pos = new int[9];//表示i行y列存放了public List> solveNQueens(int n) {//55-13dfs(n, 0);return res;}public void dfs(int n, int index){if(index==n){res.add(new ArrayList(tmp));return;}for(int j=0;j//index表示的就是行,不用再一个行的for循环if(isValid(index,j)){pos[index] = j;String s = "";for(int k = 0;kif(k!=j) s+=".";else s+="Q";}tmp.add(new String(s));dfs(n,index+1);tmp.remove(tmp.size()-1);pos[index] = 0;}}}public boolean isValid(int row, int col){for(int i=0;i//第二次写还是写错//只需要遍历到row之前的//对角线的判断是Math.abs(i-row)==Math.abs(col-pos[i])而不一定都等于1if(i==row||col==pos[i]||Math.abs(i-row)==Math.abs(col-pos[i]))return false;}return true;}
}

37 解数独

在这里插入图片描述

在这里插入图片描述
没写出来,一直想在dfs里传index,发现不太行,还是需要再看一下这个写法

class Solution {public void solveSudoku(char[][] board) {//20dfs(board);}public boolean dfs(char[][] board){for(int row=0;row<9;row++){//遍历行for(int col=0;col<9;col++){//遍历列if(board[row][col]=='.'){for(char num = '1';num<='9';num++){//遍历数字if(isValid(board,row,col,num)){board[row][col] = num;if(dfs(board)) return true;board[row][col] = '.';}}return false;}}}return true;}public boolean isValid(char[][] board, int row, int col, char num){//比较同行for(int i=0;i<9;i++){if(board[row][i]==num) return false;}//比较同列for(int i=0;i<9;i++){if(board[i][col]==num) return false;}//九宫格内int startRow = (row/3)*3;int startCol = (col/3)*3;for(int i=startRow;ifor(int j =startCol;jif(board[i][j]==num) return false;}}return true;}
}

相关内容

热门资讯

CCF BDCI“大数据平台安... 日前,数据安全领域的人工智能算法顶级赛事“CCF大数据与计算智能大赛·数字安全公开赛”...
Django实现图书馆管理系统 1.创建项目library和应用程序 django-admin startproject libra...
python UDP、TCP ... 👨‍💻个人简介: 深度学习图像领域工作者 dz...
四川旅游攻略自由行攻略跟团游6... 四川之美:自然与文化的完美融合 四川旅游推荐!当地导游-乐乐:185 8335 5758(加他微信-...
【软考笔记】2. 操作系统基本... 进程管理 进程的状态前驱图PV 操作死锁问题 进程的状态 三状态:运行态、就绪态、等待...
【小猫爪】AUTOSAR学习笔... 【小猫爪】AUTOSAR学习笔记13-功能安全之WdogM模块前言1 看门狗架构2 WdogM模块功...
使用流水线插件实现持续集成、持... 流水线插件 是基于 Rainbond 插件体系 扩展实现,通过插件化的方式࿰...
DRBG_Instantiat... rd_key  0x3b +1 0x3c =   60 60个int = 2...
餐厅菜单变“考卷”?网友吵翻了... 餐厅菜单变“考卷”?网友吵翻了,这到底是创意还是噱头?最近,一家餐厅整了个“试卷菜单”,直接火出圈了...
西瓜节上有“宝藏”!天津静海台... 天津北方网讯:5月31日傍晚,在静海台头镇北二堡村,“瓜田奇遇 清凉之旅”第十一届台头西瓜文化旅游节...
机器学习笔记之集成学习(五)梯... 机器学习笔记之集成学习——梯度提升树[GBDT]引言回顾:Boosting\text{...
vmware中centos7实... 前言 在开发收银系统SAAS版本时,采用的是centos服务器,经常需要...
开源物联网平台推荐介绍 开源物联网平台调研 文章目录开源物联网平台调研一、 调研推荐开源物联网平台及背景介绍二、社区支持度与...
“端午”假期刚开始,无锡这里上... 迎着今年“端午”假期的开启,5月30日晚,位于无锡市惠山古镇景区的“宝善坊”正式开街,上演“人从众”...
学习Java——泛型 目录 什么是泛型 泛型带来的问题 1、当泛型遇到重载 2、当泛型遇到catch 3、当泛型内包含静态...
HTTP协议协议报文结构请求响... 目录 一. 何为HTTP 1. 简单理解HTTP协议的工作过程  2. Fiddler抓包工具  2...
[ 漏洞复现篇 ] Jooml... 🍬 博主介绍 👨‍🎓 博主介绍:大家好...
【类和对象的使用的知识点——案... 文章目录类和对象的使用的知识点封装封装的意义struct和class区别成员属性设置为私有对象的初始...
青瓜虾滑饼:清爽黄瓜与鲜嫩虾滑... 准备材料:黄瓜虾滑盐白胡椒粉具体步骤: 黄瓜刨丝:将黄瓜刨成细丝。点盐杀出水分:在黄瓜丝上撒适量的...