leetcode算法入门 第十一天 递归/回溯**


回溯的模板

void backtracking(参数) {
    if (终止条件) {
        存放结果;
        return;
    }

    for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {
        处理节点;
        backtracking(路径,选择列表); // 递归
        回溯,撤销处理结果
    }
}

77.组合

回溯树

ArrayList相当于是一个动态数组,LinkedList相当于一个双指针,可以直接删除列表最后一个元素。

List<List<Integer>> result = new ArrayList<>();
LinkedList<Integer> path = new LinkedList<>();
void backtracking(int n, int k, int startIndex){
    if(path.size() == k){
        result.add(new ArrayList<>(path));
        return;
    }
    for(int i = startIndex; i <= n - (k - path.size()) + 1; i++){
        path.add(i);
        backtracking(n, k ,i + 1);
        path.removeLast();
    }
}

public List<List<Integer>> combine(int n, int k) {
    backtracking(n, k, 1);
    return result;
}

39.组合总和

每次递归的起始位置应该是上一次加入path的元素位置,以此保证没有重复结果。

List<List<Integer>> result = new ArrayList<>();
LinkedList<Integer> path = new LinkedList<>();
void backtracking(int[] candidates, int target, int startIndex){
    if(path.stream().mapToInt(Integer::intValue).sum() == target){
        result.add(new ArrayList(path));
        return;
    }
    for(int i = startIndex; i < candidates.length; i++){
        if(candidates[i] > target - path.stream().mapToInt(Integer::intValue).sum()) continue;
        path.add(candidates[i]);
        backtracking(candidates, target ,i);
        path.removeLast();
    }
}

public List<List<Integer>> combinationSum(int[] candidates, int target) {
    backtracking(candidates, target , 0);
    return result;
}

131.分割回文串

List<List<String>> result = new ArrayList<>();
LinkedList<String> path = new LinkedList<>();
void backtracking(String s, int startIndex){
   if(startIndex == s.length()){ //遍历到最后一位分割结束
        result.add(new ArrayList<>(path));
        return;
   }
   for(int i = startIndex; i < s.length(); i++){
       if(isPalindrome(s, startIndex, i)) { //判断是否是回文串,是则加入path
           path.add(s.substring(startIndex, i + 1));
       }else continue; //不是剪枝
       backtracking(s, i+1);
       path.removeLast();
   }
}

boolean isPalindrome(String s ,  int startIndex, int endIndex){
   char[] c = s.toCharArray();
   for(int i = startIndex; i <= endIndex; i++){
       if(c[i] != c[startIndex])
           return false;
   }
   return true;
}

public List<List<String>> partition(String s) {
   backtracking(s, 0);
   return  result;
}

求字符串的所有子串

List<String> result = new ArrayList<>();
String path ="";
void backtracking(String s, int startIndex){
    if(startIndex == s.length()){
        return;
    }
    for(int i = startIndex; i < s.length(); i++){
        char[] c = s.toCharArray();
        path = path + c[i];
        result.add(path);
        backtracking(s, i + 1);
        path = path.substring(0,path.length()-1);
    }
}

public List<String> combineAll(String s){
    backtracking(s, 0);
    return result;
}

784.字母大小写全排列

每次都将现在的字符串加入结果,

List<String> re = new ArrayList<>();
int dis = 'A' - 'a';
public List<String> letterCasePermutation(String s) {
    if(s.length() == 0) return re;
    char[] c = s.toCharArray();
    backtracking(c , 0);
    return re;
}

void backtracking(char[] c, int startIndex){
    re.add(String.valueOf(c));
    for(int i = startIndex; i < c.length; i++){
        if (Character.isDigit(c[i])) continue;
        if (Character.isLowerCase(c[i])){
            c[i] = (char)(c[i] + dis);
            backtracking(c , i+1);
            c[i] = (char)(c[i] - dis);
        }else {
            c[i] = (char)(c[i] - dis);
            backtracking(c , i+1);
            c[i] = (char)(c[i] + dis);
        }

    }
}

//回溯 字母ASCII: A 0100 0001   a 01100 0001 第五位异或即可实现转化
private void backTrack(char[] chars, int start){
    res.add(String.valueOf(chars));
    for(int i = start; i < chars.length;i++){
        if(chars[i] > '9'){
            chars[i] ^= 32;
            backTrack(chars,i+1);
            chars[i] ^= 32;
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值