【算法】剪枝&回溯

剪枝&回溯

剑12 矩阵中的路径@@

请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一格开始,每一步可以在矩阵中向左、右、上、下移动一格。如果一条路径经过了矩阵的某一格,那么该路径不能再次进入该格子。例如,在下面的3×4的矩阵中包含一条字符串“bfce”的路径(路径中的字母用加粗标出)。

[[“a”,“b”,“c”,“e”],
[“s”,“f”,“c”,“s”],
[“a”,“d”,“e”,“e”]]

但矩阵中不包含字符串“abfb”的路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入这个格子。

示例 1:

输入:board = [[“A”,“B”,“C”,“E”],[“S”,“F”,“C”,“S”],[“A”,“D”,“E”,“E”]], word = “ABCCED”
输出:true
示例 2:

输入:board = [[“a”,“b”],[“c”,“d”]], word = “abcd”
输出:false

来源:力扣(LeetCode)

分析:经典回溯,但此题只要求返回true or false,能返回所有路径吗?

friend ostream &operator<<(ostream &out, const vector<vector<char>> &board)
{
   
//重载 << ,用于调试输出二维数组
    for (auto i : board)
    {
   
        for (auto j : i)
        {
   
            out << j << " ";
        }
        out << endl;
    }
    out << endl;
    return out;
}
bool backtrack(vector<vector<char>> &board, int row, int col,
               const string &word, int idx)
{
   
    //正确返回终止条件,找到一个正确分支即终止
    if (idx == word.size())
        return true;
    //数组越界终止条件
    if (row < 0 || row >= board.size() ||
        col < 0 || col >= board[0].size())
        return false;
    //如果表格当前字符不等于欲匹配字符,剪掉此分支
    //这样还在增长的分支就是可能正确的分支
    if (word[idx] != board[row][col])
        return false;
    //设置标记位,如果后续回到此位置,比对字符即知
    board[row][col] = '*';
    //往四个方向走,有一个方向返回true,程序返回true
    if (backtrack(board, row - 1, col, word, idx + 1) ||
        backtrack(board, row + 1, col, word, idx + 1) ||
        backtrack(board, row, col - 1, word, idx + 1) ||
        backtrack(board, row, col + 1, word, idx + 1))
        return true;
    //回溯。走不通时该位置还原为本来的字母
    board[row][col] = word[idx];
    //cout<<board;
    //没有分支返回true。程序返回false
    return false;
}
bool exist(vector<vector<char>> &board, string word)
{
   
    if (board.empty() || board[0].empty())
        return word.empty();
    for (int row = 0; row < board.size(); ++row)
    {
   
        for (int col = 0; col < board[0].size(); ++col)
        {
   
        //暴力搜索每一点作为起点
            if (backtrack(board, row, col, word, 0))
                return true;
        }
    }
    return false;
};

剑13.机器人的运动范围

地上有一个m行n列的方格,从坐标 [0,0] 到坐标 [m-1,n-1] 。一个机器人从坐标 [0, 0] 的格子开始移动,它每次可以向左、右、上、下移动一格(不能移动到方格外),也不能进入行坐标和列坐标的数位之和大于k的格子。例如,当k为18时,机器人能够进入方格 [35, 37] ,因为3+5+3+7=18。但它不能进入方格 [35, 38],因为3+5+3+8=19。请问该机器人能够到达多少个格子?

示例 1:

输入:m = 2, n = 3, k = 1
输出:3
示例 1:

输入:m = 3, n = 1, k = 0
输出:1

第一版代码

根据上面一题直接写出此题的代码,提交结果为超时,本地运行超时用例时等待很久,说明有死循环。本着“不放弃每一段代码”的精神,我决定debug后再看书上的答案
在这里插入图片描述

class Solution {
   
public:
    int K;
    friend ostream &operator<<(ostream &
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值