每日刷题记录 (六)
文章目录
- 第一题: 剑指 Offer II 079. 所有子集
- 解题思路:
- 代码实现:
- 第二题: 剑指 Offer II 080. 含有 k 个元素的组合
- 解题思路:
- 代码实现:
- 第三题: 剑指 Offer II 081. 允许重复选择元素的组合
- 解题思路:
- 代码实现:
- 第四题: 剑指 Offer II 082. 含有重复元素集合的组合
- 解题思路:
- 代码实现:
- 第五题: 剑指 Offer II 083. 没有重复元素集合的全排列
- 解题思路:
- 代码实现:
- 第六题: 剑指 Offer II 084. 含有重复元素集合的全排列
- 解题思路:
- 代码实现:
- 第七题: 剑指 Offer II 085. 生成匹配的括号
- 解题思路:
- 代码实现:
- 第八题: 剑指 Offer II 086. 分割回文子字符串
- 解题思路
- 代码实现:
第一题: 剑指 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) {// 剪枝1if(left < 0 || right <0) return;// 剪枝2if(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;}
}
每日刷题记录 (六)相关推荐
- 每日刷题记录(十六)
目录 第一题:爬楼梯 解题思路: 代码实现: 第二题:不同路径 解题思路: 代码实现: 第三题:三角形最小路径和 解题思路: 代码实现: 第四题:最大子数组和 解题思路: 代码实现: 第五题:打家劫舍 ...
- 每日刷题记录 (十五)
文章目录 第一题: 剑指 Offer 57. 和为s的两个数字 解题思路: 代码实现: 第二题: 剑指 Offer 57 - II. 和为s的连续正数序列 解题思路: 代码实现: 第三题: 剑指 Of ...
- 每日刷题记录 (八)
文章目录 第一题: 剑指 Offer II 052. 展平二叉搜索树 解题思路: 代码实现: 第二题: 剑指 Offer II 053. 二叉搜索树中的中序后继 解题思路: 代码实现: 第三题: 剑指 ...
- 每日刷题记录 (二十)
文章目录 第一题: 16. 最接近的三数之和 解题思路: 代码实现: 第二题: 43. 字符串相乘 解题思路: 代码实现: 第三题: 59. 螺旋矩阵 II 解题思路: 代码实现: 第四题: 89. ...
- 每日刷题记录 (一)
文章目录 第一题: 按摩师 解题思路: 代码实现: 第二题: 主要元素 解题思路: 代码实现: 第三题: 第 k 个数 解题思路: 代码实现: 第四题: 连续数列 解题思路: 代码实现: 第五题: 面 ...
- 每日刷题记录 (十七)
文章目录 第一题: 剑指 Offer 33. 二叉搜索树的后序遍历序列 解题思路: 代码实现: 第二题: 剑指 Offer 34. 二叉树中和为某一值的路径 解题思路: 代码实现: 第三题: 剑指 O ...
- 每日刷题记录 (二十七)
文章目录 第一题: 1108. IP 地址无效化 解题思路: 代码实现: 第二题: 1431. 拥有最多糖果的孩子 解题思路: 代码实现: 第三题: 1720. 解码异或后的数组 解题思路: 代码实现 ...
- 每日刷题记录(十二)
目录 第一题:Fibonacci数列 解题思路: 代码实现: 第二题:合法括号序列判断 解题思路: 代码实现: 第三题:求最小公倍数 解题思路: 代码实现: 第四题:两种排序方法 解题思路: 代码实现 ...
- Codeforces 刷题记录(已停更)
Codeforces 每日刷题记录 (已停更) 打'+'是一些有启发意义的题目,部分附上一句话题解,每日更新3题,大部分题目较水. Day ID Problem Tutorial Note 1 1 + ...
最新文章
- WPF oxyPlot 使用总结
- Android 利用方向传感器获得手机的相对角度
- Python基础练习题,你会吗?
- STM32 C/C++ uCOSII 函数调用return 无法返回或者函数无法正常反回上一层函数的问题
- 还不起9亿?有人建议为范冰冰发行一款私募ABS产品融资!
- 服务器驱动器输入信号,伺服驱动器超大齿轮比驱动控制方法
- MusicPlayer音乐播放器Android
- Activity启动模式singleTask模式
- 稳压二极管原理及使用
- Oracle对索引做统计,Oracle收集索引统计信息
- 2021-2022 ICPC, NERC, Northern Eurasia Onsite C Connect the Points
- 苹果公司的电脑产品及其历史
- 【腾讯云】音视频存储管理CVS
- 【54期】Java序列化三连问,是什么?为什么需要?如何实现?
- 《追风筝的人》读书笔记
- TexturePacker入门记事
- C语言实现简单的电梯控制系统
- Linux命令之复制文件或目录cp
- 玩转ChatGPT:Auto-GPT项目部署与测评
- 无人驾驶 | 自动驾驶技术和机器人技术的对比
热门文章
- axios下载文件乱码问题 无法解压 文件损坏
- 论文写作——如图所示
- 5M1270ZT144A5N CPLD 980MC 6.2NS 144TQFP /5M1270ZT144C5N
- 去香港读研——申请全过程
- iphone ios 视频采集AVCaptureSessionPresetHigh/Medium/Low分辨率等参数
- 对视频的分辨率大小进行裁剪
- Java遍历list集合转换成PDF
- 微电网经济调度(风、光、柴油机、蓄电池、电网交互)(Matlab代码实现)
- win10关闭了微软服务器,win10自带安全软件怎么关闭|win10关闭自带杀毒软件的两种方法...
- 随机事件和概率及概率的性质