您现在的位置是:首页 >技术交流 >回溯算法编程题集合(leetcode)网站首页技术交流
回溯算法编程题集合(leetcode)
给定一个整数数组 nums 和一个正整数 k,找出是否有可能把这个数组分成 k 个非空子集,其总和都相等。
示例 1:
输入: nums = [4, 3, 2, 3, 5, 2, 1], k = 4
输出: True
说明: 有可能将其分成 4 个子集(5),(1,4),(2,3),(2,3)等于总和。
示例 2:输入: nums = [1,2,3,4], k = 3
输出: false来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/partition-to-k-equal-sum-subsets
本题一开始本人打算使用动态规划,一开始的思路是求得nums数组的和然后除以k赋值为target,然后利用动态规划01背包求nums数组中可以组成target的方案数,但是运用此题理解有偏差,因为是划分子集所以有些数组元素不能重复使用。
选用leetcode精选题解
public boolean canPartitionKSubsets(int[] nums, int k) {
int sum = 0;
for (int i = 0; i < nums.length; i++) sum += nums[i];
if (sum % k != 0) return false;
int target = sum / k;
// 排序优化
Arrays.sort(nums);
int l = 0, r = nums.length - 1;
while (l <= r) {
int temp = nums[l];
nums[l] = nums[r];
nums[r] = temp;
l++;
r--;
}
return backtrack(nums, 0, new int[k], k, target);
}
private boolean backtrack(int[] nums, int index, int[] bucket, int k, int target) {
// 结束条件优化
if (index == nums.length) return true;
for (int i = 0; i < k; i++) {
// 优化点二
if (i > 0 && bucket[i] == bucket[i - 1]) continue;
// 剪枝
if (bucket[i] + nums[index] > target) continue;
bucket[i] += nums[index];
if (backtrack(nums, index + 1, bucket, k, target)) return true;
bucket[i] -= nums[index];
}
return false;
}
难度中等639收藏分享切换为英文接收动态反馈
给你一个整数数组
nums
,找出并返回所有该数组中不同的递增子序列,递增子序列中 至少有两个元素 。你可以按 任意顺序 返回答案。数组中可能含有重复元素,如出现两个整数相等,也可以视作递增序列的一种特殊情况。
示例 1:
输入:nums = [4,6,7,7] 输出:[[4,6],[4,6,7],[4,6,7,7],[4,7],[4,7,7],[6,7],[6,7,7],[7,7]]示例 2:
输入:nums = [4,4,3,2,1] 输出:[[4,4]]
public static List<List<Integer>> findSubsequences(int[] nums) {
List<List<Integer>> lists=new ArrayList<>();
if(nums.length<2)
return lists;
List<Integer> list=new ArrayList<>();
backtreeing(lists,list,0,nums);
return lists;
}
public static void backtreeing(List<List<Integer>> lists,List<Integer> list,int start,int nums[]){
if(list.size()>=2){
lists.add(new ArrayList<>(list));
}
//set做树层剪枝,同一层已经使用过的元素再此使用就跳出
HashSet<Integer> set=new HashSet<>();
for(int i=start;i<nums.length;i++){
if(i>start&&set.contains(nums[i]))
continue;
if(list.size()==0||nums[i]>=list.get(list.size()-1)){
list.add(nums[i]);
set.add(nums[i]);
backtreeing(lists,list,i+1,nums);
list.remove(list.size()-1);
}
}
}
难度中等2418收藏分享切换为英文接收动态反馈
给定一个仅包含数字
2-9
的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
示例 1:
输入:digits = "23" 输出:["ad","ae","af","bd","be","bf","cd","ce","cf"]示例 2:
输入:digits = "" 输出:[]示例 3:
输入:digits = "2" 输出:["a","b","c"]
public List<String> letterCombinations(String digits) {
List<String> list=new ArrayList<>();
if(digits==null||digits.length()==0)
return list;
char[] chars = digits.toCharArray();
StringBuilder stringBuilder=new StringBuilder();
Map<Character, String> phoneMap = new HashMap<Character, String>() {{
put('2', "abc");
put('3', "def");
put('4', "ghi");
put('5', "jkl");
put('6', "mno");
put('7', "pqrs");
put('8', "tuv");
put('9', "wxyz");
}};
backtreeing(chars,list,phoneMap,stringBuilder,0);
return list;
}
public void backtreeing(char[] chars,List<String> list,Map<Character,String> map, StringBuilder stringBuilder,int start){
if(start==chars.length){
list.add(stringBuilder.toString());
return;
}
String s1 = map.get(chars[start]);
for(int i=0;i<s1.length();i++){
stringBuilder.append(s1.charAt(i));
backtreeing(chars,list,map,stringBuilder,start+1);
stringBuilder.deleteCharAt(stringBuilder.length()-1);
}
}
难度中等1203收藏分享切换为英文接收动态反馈
有效 IP 地址 正好由四个整数(每个整数位于
0
到255
之间组成,且不能含有前导0
),整数之间用'.'
分隔。
- 例如:
"0.1.2.201"
和"192.168.1.1"
是 有效 IP 地址,但是"0.011.255.245"
、"192.168.1.312"
和"192.168@1.1"
是 无效 IP 地址。给定一个只包含数字的字符串
s
,用以表示一个 IP 地址,返回所有可能的有效 IP 地址,这些地址可以通过在s
中插入'.'
来形成。你 不能 重新排序或删除s
中的任何数字。你可以按 任何 顺序返回答案。示例 1:
输入:s = "25525511135" 输出:["255.255.11.135","255.255.111.35"]示例 2:
输入:s = "0000" 输出:["0.0.0.0"]示例 3:
输入:s = "101023" 输出:["1.0.10.23","1.0.102.3","10.1.0.23","10.10.2.3","101.0.2.3"]
public static List<String> restoreIpAddresses(String s) {
List<String> list=new ArrayList<>();
if(s.length()<4)
return list;
String[] num=new String[4];
backtreeing(s,list,0,0,num);
return list;
}
public static void backtreeing(String s,List<String> list,int start,int count,String[] num){
if(count==4){
if(start==s.length()){
StringBuilder stringBuilder=new StringBuilder();
for(int i=0;i<num.length;i++){
stringBuilder.append(num[i]);
if(i!=3)
stringBuilder.append(".");
}
list.add(stringBuilder.toString());
}
return;
}
//if 语句不能放在外面因为在执行过程中start会超出字符串长度,导致异常,比如10.10.23 count=3,start=6的时候就会错误
// if(s.charAt(start)=='0'){
// num[count] = "0";
// backtreeing(s, list, start + 1, count + 1, num);
// return;
// }
StringBuilder stringBuilder=new StringBuilder();
for(int i=start;i<s.length();i++){
if(s.charAt(start)=='0'){
num[count] = "0";
backtreeing(s, list, start + 1, count + 1, num);
return;
}
if(i>start+2)
break;
String substring = s.substring(start, i + 1);
if(Integer.parseInt(substring)>255)
continue;
stringBuilder.append(substring);
num[count]=stringBuilder.toString();
backtreeing(s,list,i+1,count+1,num);
stringBuilder.delete(0,stringBuilder.length()+1);
}
}