40. 组合总和 II(中等)
思路:相比39题,需要去掉for中==last的元素,避免同一个数搜索两遍
class Solution {
private List<List<Integer>> res ;
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
res = new ArrayList<>();
List<Integer> ans = new ArrayList<>();
Arrays.sort(candidates);
int last = 0;
for(int i=0;i<candidates.length;i++){
if(candidates[i]==last)continue;
ans.add(candidates[i]);
dfs(candidates,ans,target-candidates[i],i);
ans.remove(ans.size()-1);
last = candidates[i];
}
return res;
}
public void dfs(int[] candidates,List<Integer> ans,int target, int it){
if(target == 0){
res.add(new ArrayList<>(ans));
return ;
}
int last = 0;
for(int i=it+1;i<candidates.length&&candidates[i]<=target;i++){
if(candidates[i]==last)continue;
ans.add(candidates[i]);
dfs(candidates,ans,target-candidates[i],i);
ans.remove(ans.size()-1);
last = candidates[i];
}
}
}
131. 分割回文串(中等)
思路:一段一段切割,然后判断。
class Solution {
List<List<String>> res ;
public List<List<String>> partition(String s) {
res = new ArrayList<>();
List<String> ans = new ArrayList<>();
if(isPartition(s)){
ans.add(s);
res.add(new ArrayList<>(ans));
ans.clear();
}
for(int i=1;i<s.length();i++){
String temp = s.substring(0,i);
if(isPartition(temp)){
String str = s.substring(i);
ans.add(temp);
dfs(str,ans);
ans.remove(ans.size()-1);
}
}
return res;
}
public void dfs(String s,List<String> ans){
if(isPartition(s)){
ans.add(s);
res.add(new ArrayList<>(ans));
ans.remove(ans.size()-1);
}
for(int i=1;i<s.length();i++){
String temp = s.substring(0,i);
if(isPartition(temp)){
String str = s.substring(i);
ans.add(temp);
dfs(str,ans);
ans.remove(ans.size()-1);
}
}
}
public boolean isPartition (String str){
int len = str.length();
for(int i=0;i<len/2;i++){
if(str.charAt(i)!=str.charAt(len-1-i))
return false;
}
return true;
}
}
93. 复原 IP 地址(中等)
问题:“00”的判断;大于Int的String数转int
class Solution {
List<String> res ;
public List<String> restoreIpAddresses(String s) {
res = new ArrayList<>();
if(s.length()<4)return res;
for(int i=1;i<=3;i++){
String t = s.substring(0,i);
if(isIPNumber(t)){
dfs(s.substring(i),3,t);
}
}
return res;
}
public void dfs(String s,int cnt,String ans){
if(cnt==1){
if(s.length()<=3&&isIPNumber(s)){
String tp = ans+"."+s;
res.add(tp);
}
return ;
}
for(int i=1;i<=3&&i<s.length();i++){
String t = s.substring(0,i);
if(isIPNumber(t)){
String tp = ans+"."+t;
dfs(s.substring(i),cnt-1,tp);
}
}
}
public boolean isIPNumber(String num){
if(num.length()>3)return false;
int n = Integer.parseInt(num);
if(n!=0&&num.charAt(0)=='0')return false;
if(n==0&&num.length()>1)return false;
if(n<0||n>255)return false;
return true;
}
}
78. 子集(中等)
思路:都知道子集的个数是2^n,原理就是,你每逮住一个元素,你问他去不去子集,去和不去是两种选择。每个元素都有两种选择,那么就是2的n次方种可能。我们就模拟这个过程,每次递归一个元素,都有加入和不加入子集两种可能。
class Solution {
List<List<Integer>> res ;
public List<List<Integer>> subsets(int[] nums) {
res = new ArrayList<>();
List<Integer> ans = new ArrayList<>();
dfs(nums,0,ans);
return res;
}
public void dfs(int[] nums,int it,List<Integer> ans){
if(it == nums.length){
res.add(new ArrayList<>(ans));
return ;
}
// 不加入子集
dfs(nums,it+1,ans);
// 加入子集
ans.add(nums[it]);
dfs(nums,it+1,ans);
// 回溯
ans.remove(ans.size()-1);
}
}