算法通关村第十八关 | 白银 | 回溯热门问题

1.组合总和问题

原题:力扣39.

元素可以重复拿取,且题目的测试用例保证了组合数少于 150 个。

class CombinationSum {
   
    List<List<Integer>> res = new ArrayList<>();
    List<Integer> path = new ArrayList<>();

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

    // u 是开始遍历的索引
    public void dfs(int[] c, int u, int target) {
   
        if (target < 0) {
   
            return;
        }
        if (target == 0) {
   
            res.add(new ArrayList(path));
            return;
        }
        // 由于元素可以重复,所以 i 从传入的 i 开始继续遍历
        for (int i = u; i < c.length; i++) {
   
            if (c[i] <= target) {
   
                path.add(c[i]);
                dfs(c, i, target - c[i]);
                path.remove(path.size() - 1);
            }
        }
    }
}

2.分割回文串

原题:力扣131.

先取第一个数与后边分开,再取前两个数与后边分开,以此类推…

class Pritition {
   
    List<List<String>> lists = new ArrayList<>();
    Deque<String> deque = new LinkedList<>();

    public List<List<String>> partition(String s) {
   
        backTracking(s, 0);
        return lists;
    }

    // 回溯算法
    private void backTracking(String s, int startIndex) {
   
        // 已经遍历完成,可以作为一组方案添加到 lists 里面
        if (startIndex >= s.length()) {
   
            lists.add(new ArrayList(deque));
            return;
        }
        
        for (int i = startIndex; i < s.length(); i++) {
   
            if (isPalindrome(s, startIndex, i)) {
   
                String str = s.substring(startIndex, i + 1);
                deque.addLast(str);
            } else {
   
                continue;
            }
            backTracking(s, i + 1);
            deque.removeLast();
        }
    }

    // 判断回文串
    private boolean isPalindrome(String s, int startIndex, int end) {
   
        for (int i = startIndex, j = end; i < j; i++, j--) {
   
            if (s.charAt(i) != s.charAt(j)) {
   
                return false;
            }
        }
        return true;
    }
}

3.子集问题

原题:力扣78.

子集问题往往是要取得所有结果,所以不需要找到满足条件的结果或者剪枝。

class Subsets {
   
    List<List<Integer>> result = new ArrayList<>();
    LinkedList<Integer> path = new LinkedList<>();

    public List<List<Integer>> subsets(int[] nums) {
   
        // 空集合
        if (nums.length == 0) {
   
            result.add(new ArrayList<>());
            return result;
        }
        subsetsHelper(nums, 0);
        return result;
    }
    private void subsetsHelper(int[] nums, int startIndex) {
   
        // 之前的可以作为一个子集
        result.add(new ArrayList<>(path));
        if (startIndex >= nums.length) {
   
            return;
        }
        for (int i = startIndex; i < nums.length; i++) {
   
            path.add(nums[i]);
            subsetsHelper(nums, i + 1);
            path.removeLast();
        }
    }
}

4.排列问题

原题:力扣46.

class Permute {
   
    List<List<Integer>> result = new ArrayList<>();
    LinkedList<Integer> path = new LinkedList<>();
    boolean[] used;
    public List<List<Integer>> permute(int[] nums) {
   
        if (nums.length == 0) {
   
            return result;
        }
        used = new boolean[nums.length];
        permuteHelper(nums);
        return result;
    }
    private void permuteHelper(int [] nums) {
   
        // 排列完了,加入结果
        if (path.size() == nums.length) {
   
            result.add(new ArrayList<>(path));
            return;
        }
        for (int i = 0; i < nums.length; i++) {
   
            if (used[i]) {
   
                continue;
            }
            used[i] = true;
            path.add(nums[i]);
            permuteHelper(nums);
            path.removeLast();
            used[i] = false;
        }
    }
}

5.字母大小写全排列

原题:力扣784.

数字是干扰项,排除就好。字母的大小写转换用异或 32 来操作。

class LetterCasePermutation {
   
    public List<String> letterCasePermutation(String s) {
   
        List<String> ans = new ArrayList<String>();
        dfs(s.toCharArray(), 0, ans);
        return ans;
    }
    public void dfs(char[] arr, int pos, List<String> res) {
   
        while (pos < arr.length && Character.isDigit(arr[pos])) {
   
            pos++;
        }
        if (pos == arr.length) {
   
            res.add(new String(arr));
            return;
        }
        arr[pos] ^= 32;
        dfs(arr, pos + 1, res);
        arr[pos] ^= 32;
        dfs(arr, pos + 1, res);
    }
}

6.单词搜索

原题:力扣79.

class Exist {
   
    public boolean exist(char[][] board, String word) {
   
        char[] words = word.toCharArray();
        for (int i = 0; i < board.length; i++) {
   
            for (int j = 0; j < board[0].length; j++) {
   
                // 这里不要简写
                if (dfs(board, words, i, j, 0)) {
   
                    return true;
                }
            }
        }
        return false;
    }
    // k 代表了 word 取到了第几个字符
    boolean dfs(char[][] board, char[] words, int i, int j, int k) {
   
        if (i >= board.length || i < 0 || j >= board[0].length || j < 0 || board[i][j] != words[k]) {
   
            return false;
        }
        // 终止条件
        if (k == words.length - 1) {
   
            return true;
        }
        // 改成终止符,不允许再次访问
        board[i][j] = '\0';
        boolean res = dfs(board, words, i + 1, j, k + 1) || 
        				dfs(board, words, i - 1, j, k + 1) ||
                        dfs(board, words, i, j + 1, k + 1) || 
        				dfs(board, words, i, j - 1, k + 1);
        // 使用后再改回来,即前面题目的 remove 操作
        board[i][j] = words[k];
        return res;
    }
}

如果对您有帮助,请点赞关注支持我,谢谢!
如有错误或者不足之处,敬请指正!
个人主页:星不易
算法通关村专栏:不易|算法通关村

相关推荐

  1. 算法通关 | 白银 | 回溯热门问题

    2023-12-12 12:38:04       70 阅读
  2. 算法通关 | 青铜 | 回溯

    2023-12-12 12:38:04       63 阅读
  3. 算法通关 | 黄金 | 较难的回溯问题

    2023-12-12 12:38:04       61 阅读
  4. 算法通关|白银|数字与数学高频问题

    2023-12-12 12:38:04       64 阅读
  5. 算法通关 | 白银 | 贪心高频问题

    2023-12-12 12:38:04       64 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2023-12-12 12:38:04       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2023-12-12 12:38:04       101 阅读
  3. 在Django里面运行非项目文件

    2023-12-12 12:38:04       82 阅读
  4. Python语言-面向对象

    2023-12-12 12:38:04       91 阅读

热门阅读

  1. springboot中使用aop实现方法拦截处理

    2023-12-12 12:38:04       57 阅读
  2. 打包CSS

    打包CSS

    2023-12-12 12:38:04      59 阅读
  3. C语言实现求1000以内的全部亲密数

    2023-12-12 12:38:04       61 阅读
  4. 在 WordPress 循环中排除置顶文章

    2023-12-12 12:38:04       64 阅读
  5. 力扣70. 爬楼梯

    2023-12-12 12:38:04       63 阅读
  6. 纯js+css实现手风琴

    2023-12-12 12:38:04       56 阅读
  7. linux常用命令-curl命令详解(超详细)

    2023-12-12 12:38:04       53 阅读
  8. LeetCode160. Intersection of Two Linked Lists

    2023-12-12 12:38:04       45 阅读
  9. GO设计模式——2、工厂方法模式(创建型)

    2023-12-12 12:38:04       61 阅读
  10. 利用playbook源码部署lamp

    2023-12-12 12:38:04       53 阅读
  11. 【APP安卓测试工具】adb(Android Debug Bridge)

    2023-12-12 12:38:04       41 阅读
  12. mysql分别在windows和linux下的备份策略

    2023-12-12 12:38:04       64 阅读
  13. TCP和UDP

    TCP和UDP

    2023-12-12 12:38:04      48 阅读