4.2-4.3.回溯的最佳实践:解数独、括号生成、

37. 解数独

在这里插入图片描述
在这里插入图片描述
1.题目分析
回溯算法,有数的地方跳过,没有数的地方在选择列表内依次填入1~9这9个数字,直到找到为止。

2.代码

class Solution {
    public void solveSudoku(char[][] board) {
        backTrack(board,0,0);
    }
    
    public boolean backTrack(char[][] board, int i, int j){
        int row = 9, colum = 9;
        if (j==colum){
            穷举到最后一列,则换到下一列重新开始
            return backTrack(board, i+1, 0);
        }
        遍历完了最后一行,找到了
        if (i==row){
            return true;
        }
        
        1.当该小格有数字时,直接跳过
        if (board[i][j] != '.'){
            return backTrack(board, i, j+1);
        }

        选择列表
        for (char ch='1'; ch <='9';ch++) {
            1.参数不合法,跳过
            if (!isValid(board,i,j,ch))
                continue;
            
            2.参数合法,填入
            board[i][j] = ch;
            
            3.进行回溯,如果找到整个数独可行解,立即结束
            if (backTrack(board, i, j+1)){
                return true;
            }
            
            4.撤销选择
            board[i][j] = '.';
        }
        
        5. 穷举完1-99个数字,依然没有则没有找到可行解
        return false;
        
    }


    验证要填入的数字是否合法
    boolean isValid(char[][] board,int r,int c,char ch){

        for (int i = 0; i < 9; i++) {
            验证同一行
            if (board[r][i] == ch) return false;
            验证同一列
            if (board[i][c] == ch) return false;
            验证同一小方格
            if (board[(r/3)*3+i/3][(c/3)*3+i%3] == ch) return false;
        }
        return true;
    }
}

22. 括号生成

在这里插入图片描述
1.题目分析——利用2个特性

  • 1.合法的括号,肯定是左右括号的数量相等;
  • 2.合法的1个括号组合p,必然对于0 <= i < len§,始终有左括号的数量 >= 右括号的数量。
    • ())( ,可知到了第3个括号时,左括号数量 < 右括号数量,不合法

2.代码

class Solution {
    List<String> res;
    public List<String> generateParenthesis(int n) {
        res = new ArrayList<>();
        StringBuilder sb = new StringBuilder();
        backTrack(n,n,sb);
        return res;
    }

    public void backTrack(int left, int right,StringBuilder sb){

        递归终止条件 剪枝条件
        	1.不合法
        if (left < 0 || right < 0)
            return;
        	2.特性2,不合法,说明此时右括号使用的比左括号还多
        if (right < left)
            return;
        	3.说明此时已经有了n对合法括号
        if (right == 0 && left == 0){
            res.add(new String(sb.toString()));
            return;
        }
        
        选择列表: 左右括号
        
        1.做选择
        sb.append('(');
        2.回溯
        backTrack(left-1, right, sb);
        3.撤销选择
        sb.deleteCharAt(sb.length()-1);

        1.做选择
        sb.append(')');
        2.回溯
        backTrack(left, right-1, sb);
        3.撤销选择
        sb.deleteCharAt(sb.length()-1);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值