[LeetCode]-回溯-2

前言

记录 LeetCode 刷题时遇到的回溯相关题目,第二篇。

93. 复原 IP 地址

回溯函数 backTrack(int index,int offset) 表示从原字符串中 offset 位置开始 (包括 offset) 选数来凑出 IP 地址中第 index 个数 (index 从 0 开始)

class Solution {int[] numIndex = new int[4]; //存放那四个数private char[] chars;int sLength;List<String> res = new LinkedList<>();public void backTrack(int index,int offset){if(index == 4){ // 边界1,当index增长到4,说明已经凑出了四个数,但是 offset 不等于字符串长度的话,说明后面还有数字没有被选,所以回溯if(offset == sLength) res.add(numIndex[0] + "." + numIndex[1] + "." + numIndex[2] + "." + numIndex[3]);return;}if(offset >= sLength) return;  // 边界2,offset超出字符串范围if(chars[offset] == '0'){ // 剪枝1,如果第一位为 0 ,那么这一个数只能取 0numIndex[index] = 0;backTrack(index + 1,offset + 1);return;}int num = 0;//从offset 开始一个数一个数选for(int i = offset;i < sLength && i < offset + 3;i++){num = num * 10 + chars[i] - '0';if(num > 255) break;numIndex[index] = num;backTrack(index + 1,i + 1);}}public List<String> restoreIpAddresses(String s) {sLength = s.length();if(sLength < 4 || sLength > 12) return res; // 剪枝2,每个数最多只能为三位,所以整个串最多12位chars = s.toCharArray();backTrack(0,0);return res;}
}

面试题 08.08. 有重复字符串的排列组合

参考题解
对于重复的字母,在同一位置不能出现多次,例如 “qqe”,在选择 ‘e’ 以及第一个 ‘q’ 后,后续不能选择 ‘e’ 以及第二个 ‘q’,

class Solution {List<String> list = new ArrayList<>();public String[] permutation(String S) {char[] c = S.toCharArray();boolean[] used = new boolean[c.length];StringBuilder sb = new StringBuilder();backTrack(used,c,sb);String[] res = list.toArray(new String[0]);return res;}public void backTrack(int[] used , char[] c, StringBuilder sb){if (sb.length() == c.length){list.add(sb.toString());return;}for (int i = 0; i < c.length; i++) {if (!used[i]){char cur = c[i];boolean valid = true;for (int j = 0; j < i; j++) {if (!used[j] && c[j] == cur){//因为在分支选取字母是从左到右选的,所以在cur左边的字母如果used值为false,//说明这个字母在当前位置已经使用过了,同一个字母在同一位置不应该使用两次valid = false;}}if (!valid) continue;sb.append(c[i]);used[i] = true;backTrack(used, c, sb);sb.deleteCharAt(sb.length()-1);used[i] = false;}}}
}

77. 组合

定义回溯函数 backTrack(int i,int count),表示从 i 开始 (包括 i) 往后的数中选取出所有可行的组合,当前已选取了 count 个。那么为了得到问题的解,我们只需调用 backTrack(1,0) 即可

对于 backTrack 函数,如果 count 值为 k,说明当前选出的组合 cur 的数目已经达到 k 了,直接把 cur 放入 res 中;如果 i 大于 n,说明待选数已经超出范围了,进行剪枝;否则就从 i 开始直到 n 进行选数

class Solution {public List<List<Integer>> res;public List<Integer> cur;public int n;public int k;public List<List<Integer>> combine(int n, int k) {res = new ArrayList<>();cur = new ArrayList<>();this.n = n;this.k = k;backTrack(1,0);return res;}public void backTrack(int i,int count){if(count == k){res.add(new ArrayList<>(cur));return;}if(i > n) return;for(int j = i;j <= n;j++){cur.add(j);backTrack(j + 1,count + 1);cur.remove(cur.size() - 1); //回退}}
}

变形

如果给定的 n 个数不是 [1,n] 的范围,而是任意的 n 个数,且会有重复,怎么处理?
最简单的方式就是基于上面回溯的做法,把 count == k 时得到的 cur 添加到一个 Set 中,然后每次在把 cur 添加到 res 前看看 Set 中是否已存在 cur,存在的话就不添加到 res 中

679. 24 点游戏

4 个数进行 24 点游戏,我们可以先选出两个数进行运算,这样四个数就变为 3 个数;然后同理,再选出两个数进行运算,剩下两个数,再对这两个数进行运算,得到最终的结果,判断是否为 24 即可。因此很明显是一个递归的过程,对四个数选出两个数进行计算后对三个数进行递归,然后再对两个数递归…

由于对两个数运算有 6 种方式 (减跟除中两个运算数交换顺序),因此需要进行回溯从而覆盖 6 种运算方式

需要注意的:

  1. 除法运算是实数运算,所以计算结果可能是实数,所以每个数要转化为 double 处理,才不会出现 0 的运算结果
  2. 同样由于是实数运算,最后的运算结果不一定刚好等于 24,而是一个近似于 24 的实数,所以判断最后的运算结果是否为 24 需要通过与 24 做差判断差值是否足够小来判断
class Solution {public boolean judgePoint24(int[] cards) {//知道list中最多只会有4个数,直接设置好大小为4,避免扩容List<Double> list = new ArrayList<>(4);for(int i : cards){list.add((double)i);}return backTrack(list);}public boolean backTrack(List<Double> list){if(list.size() == 1){return Math.abs(list.get(0) - 24) <= 1e-6;}for(int i = 0;i < list.size() - 1;i++){for(int j = i + 1;j < list.size();j++){boolean flag = false;List<Double> tmp = new ArrayList(list);//remove后list中i之后的数据会前移,如果先remove掉较小的坐标i的话,j对应的数就发生变化了;所以要先remove掉排在后边的j,这样i对应的数就不会变化double b = tmp.remove(j);double a = tmp.remove(i);tmp.add(a + b);flag |= backTrack(tmp);tmp.set(tmp.size() - 1,a - b);flag |= backTrack(tmp);tmp.set(tmp.size() - 1,b - a);flag |= backTrack(tmp);tmp.set(tmp.size() - 1,a * b);flag |= backTrack(tmp);tmp.set(tmp.size() - 1,a / b);flag |= backTrack(tmp);tmp.set(tmp.size() - 1,b / a);flag |= backTrack(tmp);if(flag) return true;}}return false;}
}

17. 电话号码的字母组合

每个数字有对应的几个字母,我们可以先定义一个数组存放每个数字对应的所有字母,然后对原字符串进行回溯,对每一个数字选取一个对应的字母进行替换,接着继续回溯后面的数字。回溯结束后回退,选取第二个字母进行替换,再继续回溯后面的数字,直到选取完所有对应的字母

class Solution {List<String> res;StringBuilder sb;char[][] numToChars = new char[][]{{'a','b','c'},{'d','e','f'},{'g','h','i'},{'j','k','l'},{'m','n','o'},{'p','q','r','s'},{'t','u','v'},{'w','x','y','z'}};public List<String> letterCombinations(String digits) {if(digits.isEmpty()){return new ArrayList<>();}char[] cs = digits.toCharArray();res = new ArrayList<>();sb = new StringBuilder();backTrack(cs,0);return res;}public void backTrack(char[] cs,int idx){if(idx == cs.length){res.add(sb.toString());return;}char[] toChars = numToChars[cs[idx] - '2'];for(char c : toChars){sb.append(c);backTrack(cs,idx + 1);sb.deleteCharAt(sb.length() - 1);}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/686132.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

cudnn免登录下载

现在要下载cuDNN&#xff0c;点击下载的页面后都是出现要求先加入Nvidia developers才能进行下载&#xff0c;但这个注册的过程非常慢&#xff0c;常常卡在第二个步骤&#xff0c;这里根据亲身的经验介绍一个可以绕过这个注册或登陆步骤的方式直接下载cuDNN。遇到此类问题的可以…

智能传感器阅读笔记-智能传感器的发展历程、发展趋势及方向

智能传感器的发展历程 第一代智能传感器 第一代智能传感器是数字式传感器&#xff0c;指改造A/D转换模块&#xff0c;并采用数字技术进行信号处理&#xff0c;使输出信号为数字信号&#xff08;或数字编码&#xff09;的传感器&#xff0c;主要由放大器、A/D转换模块、微处理…

清华AutoGPT:掀起AI新浪潮,与GPT4.0一较高下

引言&#xff1a; 随着人工智能技术的飞速发展&#xff0c;自然语言处理&#xff08;NLP&#xff09;领域迎来了一个又一个突破。最近&#xff0c;清华大学研发的AutoGPT成为了业界的焦点。这款AI模型以其出色的性能&#xff0c;展现了中国在AI领域的强大实力。 目录 引言&…

BulingBuling - 《工作中的焦虑》 [ Anxiety at Work ]

工作中的焦虑 帮助团队建立复原力、处理不确定性和完成任务的8项策略 作者&#xff1a;阿德里安-戈斯蒂克、切斯特-埃尔顿和安东尼-戈斯蒂克 Anxiety at Work 8 Strategies to Help Teams Build Resilience, Handle Uncertainty, and Get Stuff Done By Adrian Gostick and…

工作心得——css让元素居中的方法

前言 今天在制作一个页面样式时&#xff0c;有一个要将卡片组件设置为页面水平居中需求&#xff0c;我采用的方法是将元素设为相对定位后再通过left和transform属性调成水平居中。如何让元素居中是页面设计中必不可少的&#xff0c;下面我将列举出一些常用的元素居中方法&…

【VTKExamples::PolyData】第三十二期 MergeSelections

很高兴在雪易的CSDN遇见你 VTK技术爱好者 QQ:870202403 前言 本文分享VTK样例MergeSelections,并解析接口vtkSelection & vtkExtractSelection ,希望对各位小伙伴有所帮助! 感谢各位小伙伴的点赞+关注,小易会继续努力分享,一起进步! 你的点赞就是我的动力(^U…

小何讲进程: 阻塞进程函数 wait()和waitpid()

1. wait()和waitpid()函数说明 wait() 进程一旦调用了wait(), 就立即阻塞自己,由wait自动分析是否有当前进程的某个子进程已经退出,如果让它找到了一个已经变成僵尸的子进程,wait就会收集这个子进程的信息,并把它彻底销毁后返回;如果没有找到这样一个子进程,wait就会一…

修改函数返回地址

资源下载 【免费】突破密码认证程序&#xff08;修改函数返回地址&#xff09;资源-CSDN文库 资源内容 源码 /*****************************************************************************To be the apostrophe which changed "Impossible" into "Im po…

Redis如何找出大量以某一个前缀开头的key

Redis如何找出大量以某一个前缀开头的key 使用keys命令 KEYS命令是一个非常耗费资源的命令&#xff0c;它需要在Redis中遍历整个键空间&#xff0c;因此应该尽量避免在生产环境中使用。如果需要查找的key非常多&#xff0c;可以考虑使用SCAN命令&#xff0c;或者使用其他更高效…

linux-firewalld防火墙端口转发

目的:通过统一地址实现对外同一地址暴露 1.系统配置文件开启 ipv4 端口转发 echo "net.ipv4.ip_forward 1" >> /etc/sysctl.confsysctl -p 2.查看防火墙配置端口转发之前的状态 firewall-cmd --statefirewall-cmd --list-all 3.开启 IP 伪装 firewall-cm…

LeetCode 第33天 | 1005. K 次取反后最大化的数组和 135. 分发糖果 134. 加油站

1005. K 次取反后最大化的数组和 按照绝对值大小降序排序&#xff0c;然后将负值变正&#xff0c;如果所有负值都正了&#xff0c;但是还有k余量且为奇数&#xff0c;那就将绝对值最小值&#xff08;最后一个元素&#xff09;取反&#xff0c;否则直接结束。 class Solution {…

sqlserver对已有的表插入列

现有如下的一个表&#xff1b; 现在要插入一个 人员id 列&#xff1b;如下图在设计视图的行首单击&#xff0c;选择 插入列&#xff1b; 然后添加一个 人员id 列&#xff1b; 保存&#xff0c;出现下图提示&#xff0c;不能保存设计&#xff1b; 这就直接使用sql语句更改&#…

【杂谈】裁我?我是研发,我是研发啊!

闲谈 这两年互联网是越来越不太平了&#xff0c;前有国外互联网裁员的妖风四起&#xff0c;后来寒气又传到国内&#xff0c;让我们这群打工人叫苦连天。最近有部电影蛮火的&#xff0c;叫《年会不能停》&#xff0c;感觉跟我前司很相似&#xff0c;不过好像由于今年业绩不太行…

反转链表【基础算法精讲 06】

视频地址 反转链表【基础算法精讲 06】_哔哩哔哩_bilibili 概念 链表的每一个结点都包含节点值 和1指向下一个结点的next指针 , 链表的最后一个结点指向空; 206 . 反转链表 用cur记录当前遍历到的结点 &#xff0c; 用pre表示下一个结点 &#xff0c; 用nxt表示cur的下一个…

如何修复Microsoft Edge不能以全屏模式打开​?这里提供几个故障排除方法

随着越来越多的Windows 10用户将Edge设置为默认浏览器&#xff0c;各种错误和小故障层出不穷。例如&#xff0c;许多用户抱怨他们无法在全屏模式下启动Edge。如果你正在寻找解决方案来解决这个恼人的问题&#xff0c;请按照下面的故障排除步骤进行操作。 修复Microsoft Edge不…

什么是智慧公厕,智慧公厕有哪些功能

1.什么是智慧公厕&#xff1f; 随着智慧城市的快速发展&#xff0c;公共厕所作为城市基础设施的一部分&#xff0c;也在逐步升级转型。那么&#xff0c;什么是智慧公厕&#xff1f;智慧公厕作为智慧城市的重要组成部分&#xff0c;将公共厕所的建设、设计、使用、运营和管理等…

codeforces 1500分

文章目录 1.[C. Partitioning the Array](https://codeforces.com/contest/1920/problem/C)2.[F. Greetings](https://codeforces.com/contest/1915/problem/F)3.[B. Plus and Multiply](https://codeforces.com/problemset/problem/1542/B)4.[B. Codeforces Subsequences](htt…

第4讲引入JWT前后端交互

引入JWT前后端交互 Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准&#xff08;(RFC 7519)&#xff1b; JWT就是一段字符串&#xff0c;用来进行用户身份认证的凭证&#xff0c;该字符串分成三段【头部、载荷、签证】 后端接口测试&…

【JavaSE】类和对象

面向对象概述 面向对象编程&#xff08;简称POP&#xff09;&#xff0c;其核心思想就是参照现实中的事物&#xff0c;将事物的属性特征、行为特征抽象出来&#xff0c;使用类来表示&#xff0c;当涉及到一个具体的实例时&#xff0c;就将类进行实例化&#xff0c;使用一个对象…

【镜头知识】对焦和变焦

前言 变焦 调整某几个镜片的相对位置&#xff0c;从而改变镜片组的焦距&#xff0c;进而改变图像的视场角度。 焦距和视角以及拍摄距离的关系这张图能更好的体现&#xff1a; 视角越窄&#xff0c;也意味着放大的倍数越大&#xff01; 对焦 物体反射的光线&#xff0c;有很多不…