综合回溯,剪枝,暴搜

 

目录

 

力扣1863.找出所有子集的异或总和再求和

力扣47.全排列II​编辑

力扣17.电话号码的字母组合电话号码的字母组合https://leetcode.cn/problems/letter-combinations-of-a-phone-number/​编辑

力扣22.括号生成


力扣1863.找出所有子集的异或总和再求和

class Solution {int sum;int path;//表示当前路径的返回值public int subsetXORSum(int[] nums) {dfs(nums,0);return sum;}public void dfs(int[] nums,int pos){sum+=path;for(int i=pos;i<nums.length;i++){//m添加当前数字path^=nums[i];dfs(nums,i+1);//此处,要想他回溯是什么时候回溯,是dfs走完了回溯,它会先走到下面,然后回到上一层,那么当他会到上一层时,是回溯什么,回溯到上一层的上一层,换句话说,那她就要把当前的值去除path^=nums[i];}}
}

我觉得对我这种代码能力不是很强的人来说,有几个重要的点

1.掌握各个集合的使用,2.了解内部的一些数学知识,3.了解算法的使用,我觉得这三个都很重要。

所以在这里介绍一个知识:

异或的消消乐:假如说1异或2,得出来的结果假如再异或一个2就会变回1,这也就是两个一样的还原成原先数字,这就是我们的消消乐原理。

力扣47.全排列II

讲实话,刚开始我还不会写,对全排列不是很理解,虽然前一个做了这个问题但还是生疏,到现在,真正自己去动手画一个决策树,真的就能把想要的写出来。

这个是全排列I的时候的决策树

这个全排列II和全排列I的区别,就是测设用例要求返回不重复的全排列

全排列的情况II,从合法的角度去写,如果他是第一个,可以无脑进入遍历,因为他不用考虑重复,如果他不是第一个,那么就不能有重复的,假如有重复的那么他的前一个一定是true(上一层遍历过的)否则不会成功

class Solution {List<List<Integer>>ret=new ArrayList<>();List<Integer>path=new ArrayList<>();boolean []check;public List<List<Integer>> permuteUnique(int[] nums) {check=new boolean[nums.length];Arrays.sort(nums);dfs(nums);return ret;}public void dfs(int[]nums){if(path.size()==nums.length){ret.add(new ArrayList<>(path));}for(int i=0;i<nums.length;i++){//我们去重的时候想去nums[i]==nums[i+1],万一有可能他们两个重复的不在一起呢。//所以我们要进行排序//||从左往右执行的,假如左边不成立,那么右边必定成立的情况 true的潜台词是nums[i]==nums[i-1]//i==0的原因是,他是第一个元素,我们可以大胆去使用它。if(check[i]==false&&(i==0||nums[i]!=nums[i-1]||check[i-1]==true)){path.add(nums[i]);check[i]=true;dfs(nums);path.remove(path.size()-1);check[i]=false;}}}
}

假如说我们考虑不合法的情况

当他出现不合法的情况,就要跳过,那么什么是不合法的情况呢

当他已经是true的时候,不合法,或者出现了相同的值并且他的前一个值是false的情况,那么就是这一层出现了两个相同的数,所以会有错误

class Solution {List<List<Integer>>ret=new ArrayList<>();List<Integer>path=new ArrayList<>();boolean []check;public List<List<Integer>> permuteUnique(int[] nums) {check=new boolean[nums.length];Arrays.sort(nums);dfs(nums);return ret;}public void dfs(int[]nums){if(path.size()==nums.length){ret.add(new ArrayList<>(path));}for(int i=0;i<nums.length;i++){//我们去重的时候想去nums[i]==nums[i+1],万一有可能他们两个重复的不在一起呢。//所以我们要进行排序//||从左往右执行的,假如左边不成立,那么右边必定成立的情况 true的潜台词是nums[i]==nums[i-1]//i==0的原因是,他是第一个元素,我们可以大胆去使用它。if(check[i]==true||(i!=0&&nums[i]==nums[i-1]&&check[i-1]!=true)){continue;}path.add(nums[i]);check[i]=true;dfs(nums);path.remove(path.size()-1);check[i]=false;}}
}

力扣17.电话号码的字母组合
电话号码的字母组合icon-default.png?t=N7T8https://leetcode.cn/problems/letter-combinations-of-a-phone-number/

首先映射关系是我们需要考虑的,怎么处理映射关系呢?

搞一个字符串数组即可-

2:abc 3:def。。。前两个可以空着(因为0,1没有值)

我们需要使用StringBufer path,我们要给他更改字符的时候,假如是String更改值不方便。所以我们使用StringBuffer

回溯:删除掉之前增加的那个字符

递归出口:

、class Solution {String[] hash={"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};List<String>ret=new ArrayList<>();StringBuffer path=new StringBuffer();public List<String> letterCombinations(String digits) {if(digits.length()==0){return ret;}dfs(digits,0);return ret;}
public void dfs(String digits,int pos){//为什么是等于pos,因为pos代表的是这个字符串有多长,够了就说明可以回溯了if(digits.length()==pos){ret.add(path.toString());return;
}
//把cur数组存储hash里面的字符串,pos的变化相当于是切换字符串 ,abc先a然后到达def的d
String cur=hash[digits.charAt(pos)-'0'];
//一次遍历cur里面的数组,然后path路径再次加入路径元素
for(int i=0;i<cur.length();i++){//i是表示假如说号码2,是说号码2的第几个,不是总体的长度path.append(cur.charAt(i));dfs(digits,pos+1);path.deleteCharAt(path.length()-1);
}}
}

力扣22.括号生成

要先思考,什么是有效的括号组合,必须要同时满足这两个条件,才能满足有效的括号

首先左括号数量等于右括号的数量

从头开始的任意一个字串,左括号数量>=右括号数量

n=x,n是几对的意思. 也就是说明有2x个括号

1.全局变量

左括号数量,右括号数量,(k一共多少对)

path记录路径,ret

dfs(一个参数即可)

回溯:当向上走的的时候,干掉path最后一个即可

当right==n,我们就可以返回了

class Solution {int left;int k;int right;List<String> ret=new ArrayList<>();StringBuffer path=new StringBuffer(); public List<String> generateParenthesis(int n) {k=n;dfs();return ret;}
public void dfs(){if(right==k){ret.add(path.toString());return;}
假如left<括号的对数,那么我们就可以添加左括号
//在这里其实我有一个思考,什么时候+右括号呢,这不是一直都会进入左括号吗。if(left<k){path.append("(");left++;dfs();path.deleteCharAt(path.length()-1);left--;  }
//假如left>right就可以一直+右括号if(left>right){path.append(")");right++;dfs();path.deleteCharAt(path.length()-1);right--;  }}
}

假如left<括号的对数,那么我们就可以添加左括号
在这里其实我有一个思考,什么时候+右括号呢,这不是一直都会进入左括号吗。

这也引起我的思考,后来也就一瞬间通透了,他是一直向下走,而不是横着走,这也就是深度搜索,然后回溯(走完一条路)之后向右走,((      ),假如是这样如果他就会回溯后,加入进去右括号

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

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

相关文章

【C项目】顺序表

简介&#xff1a;本系列博客为C项目系列内容&#xff0c;通过代码来具体实现某个经典简单项目 适宜人群&#xff1a;已大体了解C语法同学 作者留言&#xff1a;本博客相关内容如需转载请注明出处&#xff0c;本人学疏才浅&#xff0c;难免存在些许错误&#xff0c;望留言指正 作…

java遍历二叉树,前序遍历、中序遍历、后序遍历

static class TreeNode{int val;TreeNode left;TreeNode right;int deep;}/*** 二叉树的前序遍历&#xff0c;RLR 根左右* param root* param res*/static void accessTree1(TreeNode root,List<Integer> res){if(root null){return;}res.add(root.val);accessTree1(roo…

LeetCode 835. 图像重叠

都知道是枚举行移动 枚举列移动 脑子不清楚 一开始写的很shit&#xff0c;后来动了一下脑子&#xff0c;发现你可以处理行移动&#xff0c;然后在行移动的基础上处理列移动&#xff0c;注意RE问题就行了 class Solution { public:int largestOverlap(vector<vector<int&g…

ElementUI安装与使用指南

Element官网-安装指南 提醒一下&#xff1a;下面实例讲解是在Mac系统演示的&#xff1b; 一、开发环境配置 电脑需要先安装好node.js和vue2或者vue3 安装Node.js Node.js 中文网 安装node.js命令&#xff1a;brew install node node.js安装完后&#xff0c;输入&#xff1…

【Linux C | 网络编程】getsockname 和 getpeername函数详解及C语言例子

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…

Qt关于qss文件的添加使用

把ui设计得更加的养眼&#xff0c;肯定需要对控件的属性进行设置&#xff0c;qt中就是关于qss文件的使用。 那么如何创建和添加qss文件呢 1.新建一个文本文件的txt 2.将文本文件的后缀改为qss&#xff08;类比html&#xff09; 3.放置到项目的资源文件夹下 4.添加资源文件 5.在…

推荐系统|排序_MMOE

MMOE MMOE是指Multi-gate Mixture-of-Experts 注意看Expert后面加了s&#xff0c;说明了有多个专家。 而在MMOE中专家是指用来对输入特征计算的神经网络&#xff0c;每个神经网络根据输入计算出来的向量都会有所不同。 MMOE的低层 MMOE的上一层 通过MMOE的低层算出的向量和权…

【排序算法】C语言实现随机快排,巨详细讲解

文章目录 &#x1f680;前言&#x1f680;快排的核心过程partition&#xff08;划分过程&#xff09;&#x1f680;快排1.0&#x1f680;随机快速排序&#x1f680;稳定性 &#x1f680;前言 铁子们好啊&#xff01;继续我们排序算法今天要讲的是快排&#xff0c;通常大家所说…

nop-entropy可逆计算入门(1)

第1步&#xff1a;从大佬的gitee&#xff1a;https://gitee.com/canonical-entropy/nop-entropy下载源码&#xff0c;进行本地编译&#xff0c;具体编译看项目下的readme,想偷懒的可以下载我编译后的jar&#xff0c;放到自己的maven仓库 https://pan.baidu.com/s/15qANnrCh5RV…

C语言字符串操作函数详解①strlen函数的讲解与三种模拟实现方法(建议三连收藏)

目录 ​编辑 前言 1.strlen函数介绍 2.模拟实现strlen 2.1计数器做法 2.2不创建临时变量&#xff0c;通过递归的方法 2.3利用两个指针相减 3.结语 前言 C语言中对字符和字符串的处理很是频繁&#xff0c;但是C语言本身是没有字符串类型的&#xff0c;字符串通常放在常量…

Linux文本三剑客-grep

1.grep简介&#xff1a; grep (global search regular expression(RE) and print out the line,全面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具&#xff0c;它能使用正则表达式搜索文本&#xff0c;并把匹配的行打印出来&#xff0c;都是按行处理的。 grep 最主要…

Linux内核源码

记得看目录哦&#xff01; 1. 为什么要阅读Linux内核2. Linux0.01内核源码3. 阅读linux内核源码技巧4. linux升级内核5. linux的备份和恢复5.1 安装dump和restore5.2 使用dump完成备份5.3 使用restore完成恢复 1. 为什么要阅读Linux内核 2. Linux0.01内核源码 3. 阅读linux内核…