当前位置:网站首页>每日刷题记录 (六)
每日刷题记录 (六)
2022-06-27 12:40:00 【独一无二的哈密瓜】
文章目录
第一题: 剑指 Offer II 079. 所有子集
LeetCode: 剑指 Offer II 079. 所有子集
描述:
给定一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。
解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。
解题思路:
经典回溯题;
注意这里的剪枝.
- 剪枝1: 不能重复使用同一元素
- 剪枝2: 不能包含重复的子集
代码实现:
class Solution {
List<List<Integer>> result = new ArrayList<>();
List<Integer> ret = new ArrayList<>();
public List<List<Integer>> subsets(int[] nums) {
dfs(nums,0);
return result;
}
public void dfs(int[] nums, int start) {
result.add(new ArrayList<>(ret));
// 剪枝1: i=start 就是确保了不包含重复子集
for(int i = start; i < nums.length; i++) {
ret.add(nums[i]);
// 剪枝2: 这里传 i+1 确保了不重复使用同一个元素
dfs(nums,i+1);
ret.remove(ret.size()-1);
}
}
}
第二题: 剑指 Offer II 080. 含有 k 个元素的组合
LeetCode: 剑指 Offer II 080. 含有 k 个元素的组合
描述:
给定两个整数 n 和 k,返回 1 ... n 中所有可能的 k 个数的组合。
解题思路:
经典回溯
注意剪枝
- 剪枝1: 不能使用重复元素
- 剪枝2: 不能有重复的子集
代码实现:
class Solution {
List<List<Integer>> result = new ArrayList<>();
List<Integer> ret = new ArrayList<>();
public List<List<Integer>> combine(int n, int k) {
int[] arr = new int[n];
for(int i = 0; i < n; i++) {
arr[i] = i+1;
}
dfs(arr,0,k);
return result;
}
public void dfs(int[] arr,int start, int k) {
if(ret.size() == k) {
result.add(new ArrayList<>(ret));
return;
}
// 剪枝1: 让i=start 确保了没有重复的子集
for(int i = start; i < arr.length; i++) {
ret.add(arr[i]);
// 剪枝2: 传入 i+1 确保了不使用重复元素
dfs(arr,i+1,k);
ret.remove(ret.size() - 1);
}
}
}
第三题: 剑指 Offer II 081. 允许重复选择元素的组合
LeetCode: 剑指 Offer II 081. 允许重复选择元素的组合
描述:
给定一个无重复元素的正整数数组 candidates 和一个正整数 target ,找出 candidates 中所有可以使数字和为目标数 target 的唯一组合。
candidates 中的数字可以无限制重复被选取。如果至少一个所选数字数量不同,则两种组合是不同的。
对于给定的输入,保证和为 target 的唯一组合数少于 150 个。
解题思路:
经典回溯
注意剪枝
- 剪枝1: 不要出现重复的情况
代码实现:
class Solution {
List<List<Integer>> result = new ArrayList<>();
List<Integer> ret = new ArrayList<>();
public List<List<Integer>> combinationSum(int[] candidates, int target) {
Arrays.sort(candidates);
dfs(candidates,0,target);
return result;
}
public void dfs(int[] candidates, int start, int target) {
if (target == 0) {
result.add(new ArrayList<>(ret));
return;
}
// 剪枝1: i = start 确保不会重复子集
for(int i = start; i < candidates.length; i++) {
if(candidates[i] <= target){
ret.add(candidates[i]);
// 传入i 就会重复使用当前元素
dfs(candidates,i,target-candidates[i]);
ret.remove(ret.size()-1);
}
}
}
}
第四题: 剑指 Offer II 082. 含有重复元素集合的组合
LeetCode: 剑指 Offer II 082. 含有重复元素集合的组合
描述:
给定一个可能有重复数字的整数数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的每个数字在每个组合中只能使用一次,解集不能包含重复的组合。
解题思路:
经典回溯:
这里注意剪枝:
- 剪枝1: 不能出现重复组合
- 剪枝2: 不能重复使用元素
- 剪枝3: 数组含有重复元素
代码实现:
class Solution {
List<List<Integer>> result = new ArrayList<>();
List<Integer> ret = new ArrayList<>();
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
Arrays.sort(candidates);
boolean[] tmp = new boolean[candidates.length];
dfs(candidates,0,target,tmp);
return result;
}
public void dfs(int[] candidates, int start, int target,boolean[] tmp) {
if(target == 0) {
result.add(new ArrayList<>(ret));
return;
}
// 剪枝1: i=start确保不会出现重复组合
for (int i = start; i < candidates.length; i++) {
// 剪枝3: 使用boolean数组来标记,确保了出现重复元素的情况
if(i>0 && candidates[i] == candidates[i-1] && !tmp[i-1]){
continue;
}
if(candidates[i] <= target) {
ret.add(candidates[i]);
tmp[i] = true;
// 剪枝2: i+1就是为了确保不会出现使用自己, 但是可以使用别人
dfs(candidates,i+1,target-candidates[i],tmp);
tmp[i] = false;
ret.remove(ret.size()-1);
}
}
}
}
第五题: 剑指 Offer II 083. 没有重复元素集合的全排列
LeetCode: 剑指 Offer II 083. 没有重复元素集合的全排列
描述:
给定一个不含重复数字的整数数组 nums ,返回其 所有可能的全排列 。可以 按任意顺序 返回答案。
解题思路:
经典回溯
注意剪枝
- 剪枝1: 不能重复使用当前元素
代码实现:
class Solution {
List<List<Integer>> result = new ArrayList<>();
List<Integer> ret = new ArrayList<>();
public List<List<Integer>> permute(int[] nums) {
boolean[] tmp = new boolean[nums.length];
dfs(nums,tmp);
return result;
}
public void dfs(int[] nums, boolean[] tmp) {
if (ret.size() == nums.length) {
result.add(new ArrayList<>(ret));
return;
}
for (int i = 0; i < nums.length; i++) {
// 剪枝1: 使用boolean数组来标记, 如果当前下标是false就是没用过
if (!tmp[i]) {
tmp[i] = true;
ret.add(nums[i]);
dfs(nums,tmp);
tmp[i] = false;
ret.remove(ret.size()-1);
}
}
}
}
第六题: 剑指 Offer II 084. 含有重复元素集合的全排列
LeetCode: 剑指 Offer II 084. 含有重复元素集合的全排列
描述:
给定一个可包含重复数字的整数集合 nums ,按任意顺序 返回它所有不重复的全排列。
解题思路:
经典回溯
注意剪枝
- 剪枝1: 不能重复使用当前元素
- 剪枝2: 注意数组中重复的元素
代码实现:
class Solution {
List<List<Integer>> result = new ArrayList<>();
List<Integer> ret = new ArrayList<>();
public List<List<Integer>> permuteUnique(int[] nums) {
Arrays.sort(nums);
boolean[] tmp = new boolean[nums.length];
dfs(nums,tmp);
return result;
}
public void dfs(int[] nums, boolean[] tmp) {
if (ret.size() == nums.length) {
result.add(new ArrayList<>(ret));
return;
}
for (int i = 0; i < nums.length; i++) {
// 剪枝2: 从第二个元素开始, 如果当前元素和前一个元素是一样的,且前一个元素没有使用, 直接跳过
if(i > 0 && nums[i] == nums[i-1] && !tmp[i-1]){
continue;
}
// 剪枝1: 使用boolean数组来标记, 如果当前下标是false就是没用过
if(!tmp[i]){
tmp[i] = true;
ret.add(nums[i]);
dfs(nums,tmp);
tmp[i] = false;
ret.remove(ret.size()-1);
}
}
}
}
第七题: 剑指 Offer II 085. 生成匹配的括号
LeetCode: 剑指 Offer II 085. 生成匹配的括号
描述:
正整数 n 代表生成括号的对数,请设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。
解题思路:
这里left表示左括号数, right表示右括号数
剪枝1: right或left<0
剪枝2: right<left (确保了先使用左括号,排除了不合法情况)
代码实现:
class Solution {
public List<String> generateParenthesis(int n) {
List<String> result = new ArrayList<>();
backstrack(result,"",n,n);
return result;
}
public void backstrack(List<String> result,String str,int left, int right) {
// 剪枝1
if(left < 0 || right <0) return;
// 剪枝2
if(left > right) return;
if(left == 0 && right == 0 ) {
result.add(str);
return;
}
backstrack(result,str+"(",left-1,right);
backstrack(result,str+")",left,right-1);
}
}
第八题: 剑指 Offer II 086. 分割回文子字符串
LeetCode: 剑指 Offer II 086. 分割回文子字符串
描述:
给定一个字符串 s ,请将 s 分割成一些子串,使每个子串都是 回文串 ,返回 s 所有可能的分割方案。
回文串 是正着读和反着读都一样的字符串。
解题思路
经典回溯
注意剪枝
剪枝1: 不能重复使用当前元素
剪枝2: 不能出现重复组合
剪枝3: 必须是回文
代码实现:
class Solution {
List<List<String>> result = new ArrayList<>();
List<String> ret = new ArrayList<>();
public String[][] partition(String s) {
bfs(s,0);
String[][] str = new String[result.size()][];
int i = 0;
for(List<String> list : result){
str[i++] = list.toArray(new String[list.size()]);
}
return str;
}
public void dfs(String s,int start) {
if(s.length() == start) {
result.add(new ArrayList<>(ret));
return;
}
// 剪枝1: 不能出现重复组合
for(int i = start; i < s.length(); i++) {
// 剪枝3: 必须是回文
if(isHui(s,start,i)) {
// 剪枝2: 不能重复使用同一个元素
ret.add(s.substring(start,i+1));
bfs(s,i+1);
ret.remove(ret.size()-1);
}
}
}
public boolean isHui(String s,int left, int right) {
while(left<right) {
if(s.charAt(left) == s.charAt(right)){
left++;
right--;
}else{
return false;
}
}
return true;
}
}
边栏推荐
- nmcli team bridge 基本配置
- First encounter with dynamic programming
- application.properties 的配置信息
- JSON.stringify用法
- 带你认识图数据库性能和场景测试利器LDBC SNB
- log4j. Detailed configuration of properties
- 清楚的自我定位
- Details of istio micro service governance grid traffic management core resource controller
- Use of message queues
- 隐私计算FATE-离线预测
猜你喜欢

How to download pictures with hyperlinks

printf不定长参数原理

Word text box page feed

号称史上最难618,淘宝数据盘点你做对了吗?
![[tcapulusdb knowledge base] Introduction to tcapulusdb tcapsvrmgr tool (III)](/img/ce/b58e436e739a96b3ba6d2d33cf8675.png)
[tcapulusdb knowledge base] Introduction to tcapulusdb tcapsvrmgr tool (III)

Tiktok practice ~ public / private short video interchange

VS调试技巧

convn-N 维卷积

全球最强截图软件 Snipaste

Esp32s3 iperf routine test esp32s3 throughput test
随机推荐
hue新建账号报错解决方案
抖音实战~公开/私密短视频互转
Utilisation de la file d'attente des messages
关闭windows defender安全中心的方法
基于SSM实现招聘网站
application.properties 的配置信息
全球最强截图软件 Snipaste
硬件开发笔记(七): 硬件开发基本流程,制作一个USB转RS232的模块(六):创建0603封装并关联原理图元器件
对象序列化
数字化新星何为低代码?何为无代码
Object serialization
Picocli getting started
Steps for win10 to completely and permanently turn off automatic updates
Two TCP flow control problems
Nmcli team bridge basic configuration
Centos7 command line installation Oracle11g
[medical segmentation] unet3+
Thymeleaf的相关知识
【TcaplusDB知识库】TcaplusDB-tcapsvrmgr工具介绍(三)
Cloud native (30) | kubernetes' app store Helm