力扣100题——回溯

子集

题目

78. 子集 - 力扣(LeetCode)

思路

迭代构造子集,遍历数组,每遍历一个元素,将当前所有的子集扩展,形成包含该元素的新子集。

代码

public List<List<Integer>> subsets(int[] nums) {
        List<List<Integer>> res = new ArrayList<List<Integer>>();
        res.add(new ArrayList<Integer>());
        for(int num : nums){
            int size = res.size();
            for(int i = 0; i < size; i++){
                List<Integer> temp = new ArrayList<Integer>(res.get(i));
                temp.add(num);
                res.add(temp);
            }
        }
        return res;
    }

电话号码的字母

题目

17. 电话号码的字母组合 - 力扣(LeetCode)

思路

使用递归,排序出每一种可能

代码

List<String> res = new ArrayList<>();
    char []a = {'2','3','4','5','6','7','8','9'};
    char [][]b={{'a','b','c'},{'d','e','f'},{'g','h','i'},{'j','k','l'},{'m','n','o'},{'p','q','r','s'},{'t','u','v'},{'w','x','y','z'}};
    public List<String> letterCombinations(String digits) {
        if(digits.isEmpty()){
            return res;
        }
        char[] charArray = digits.toCharArray();
        List<char[]> chars = new ArrayList<>();
        for(char c:charArray){
            for(int i=0;i<a.length;i++){
                if(a[i]==c){
                    chars.add(b[i]);
                    continue;
                }
            }
        }
        for(int i=0;i<chars.get(0).length;i++){
            fun(String.valueOf(chars.get(0)[i]),chars,1);
        }
        return res;
    }

    private void fun(String s, List<char[]> chars, int x) {
        if(x==chars.size()||s.length()==chars.size()){
//            System.out.println(s);
            res.add(s);
            return;
        }
        for(int i=0;i<chars.get(x).length;i++){
            String c = String.valueOf(chars.get(x)[i]);
            fun(s+c,chars,x+1);
        }
    }

组合总数

题目

39. 组合总和 - 力扣(LeetCode)

思路

使用递归模拟所有可能

通过在递归函数 fun2 中,传递当前元素的索引 i,这样可以保证后续递归中只选择当前元素或后续元素,防止选择之前的元素,避免生成重复组合。

回溯时删除最后一个元素恢复状态

代码

List<List<Integer>> ans = new ArrayList<>();
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        for(int i=0;i<candidates.length;i++){
            List<Integer> list = new ArrayList<>();
            list.add(candidates[i]);
            fun2(list,target-candidates[i],candidates,i);
        }
        return ans;
    }

    private void fun2(List<Integer> list, int t, int[] candidates,int i) {
        if(t==0){
            List<Integer> in = new ArrayList<>(list);
            ans.add(in);
            return;
        }
        for (int j=i;j<candidates.length;j++) {
            if (t >= candidates[j]) {
                list.add(candidates[j]);
                fun2(list, t - candidates[j], candidates,j);
                list.removeLast();
            }
        }
    }

括号生成

题目

22. 括号生成 - 力扣(LeetCode)

思路

  • 用递归的方式构造每一个有效的括号组合。
  • 维护两个变量 leftright,分别表示左括号 ( 和右括号 ) 的剩余数量。
  • 只要左括号还有剩余,递归地尝试添加左括号;只有在右括号数量比左括号多时,才可以添加右括号。
  • 当左右括号都用完时,说明生成了一个有效的括号组合,将其加入结果列表。

代码

public List<String> generateParenthesis(int n) {
        List<String> sum = new ArrayList<>();
        if(n==0){
            return sum;
        }
        fun3(sum,"",n,n);
        return sum;
    }

    private void fun3(List<String> sum, String s, int l, int r) {
        if(l==0&&r==0){
            sum.add(s);
            return;
        }
        if(l>0){
            fun3(sum,s+"(",l-1,r);
        }
        if(r>l){
            fun3(sum,s+")",l,r-1);
        }
    }

单词搜索

题目

79. 单词搜索 - 力扣(LeetCode)

思路

dfs搜索,终止条件就是k==charArr.length

代码

public boolean exist(char[][] board, String word) {
        int n = board.length;
        int m = board[0].length;
        boolean[][] visited = new boolean[n][m];
        char[] charArray = word.toCharArray();
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                if(board[i][j]==charArray[0]){
                    visited[i][j] = true;
                    if(fun4(board,i,j,visited,charArray,1)){
                       return true;
                    }
                    visited[i][j] = false;
                }
            }
        }
        return false;
    }

    int[] aa = {0,0,-1,1};
    int[] bb = {-1,1,0,0};
    private boolean fun4(char[][] board,int x, int y, boolean[][] visited, char[] charArray,int k) {
        if(k==charArray.length){
            return true;
        }
        for(int i=0;i<4;i++){
            int xx = x+aa[i];
            int yy = y+bb[i];
            if(xx<visited.length&&xx>=0&&yy<visited[0].length&&yy>=0&&!visited[xx][yy]&&k<charArray.length){
                if(board[xx][yy]==charArray[k]){
                    visited[xx][yy] = true;
                    if(fun4(board,xx,yy,visited,charArray,k+1)){
                        return true;
                    }
                    visited[xx][yy] = false;
                }
            }
        }
        return false;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值