剑指 Offer 13. 机器人的运动范围

方法一:深度优先遍历 DFS
深度优先搜索: 可以理解为暴力法模拟机器人在矩阵中的所有路径。DFS 通过递归,先朝一个方向搜到底,再回溯至上个节点,沿另一个方向搜索,以此类推。

剪枝: 在搜索中,遇到数位和超出目标值、此元素已访问,则应立即返回,称之为 可行性剪枝 。

int is_illegal(int row, int col, int k)
{
    int sum = 0;
    while (row > 0)
    {
        sum += row % 10;
        row /= 10;
    }
    while (col > 0)
    {
        sum += col % 10;
        col /= 10;
    }
    return sum <= k;
}

void dfs(int m, int n, int k, int row, int col, int& sum, vector<vector<int>>& bitMap)
{
    //深度优先
    if (row < 0 || row >= m || col < 0 || col >= n || !is_illegal(row, col, k) || bitMap[row][col] == 1)
        return;

    bitMap[row][col] = 1;
    sum++;
    dfs(m, n, k, row, col + 1, sum, bitMap);        //先一直向右搜索
    dfs(m, n, k, row + 1, col, sum, bitMap);        //回到上一个节点一直向下搜索
}

int movingCount(int m, int n, int k) {
    vector<vector<int>> bitMap(m, vector<int>(n, 0));

    int sum = 0;
    dfs(m, n, k, 0, 0, sum, bitMap);

    return sum;
}

方法二:广度优先遍历 BFS
BFS/DFS : 两者目标都是遍历整个矩阵,不同点在于搜索顺序不同。DFS 是朝一个方向走到底,再回退,以此类推;BFS 则是按照“平推”的方式向前搜索。
BFS 实现: 通常利用队列实现广度优先遍历。

void bfs(int m, int n, int k)
{
    int sum = 0;
    vector<vector<int>> bitMap(m, vector<int>(n, 0));
    std::queue<std::pair<int, int>> que;
    que.push(std::make_pair(0, 0));
    while (!que.empty())
    {
        
        auto& node = que.front();
        if (!is_illegal(node.first, node.second, k) || bitMap[node.first][node.second] == 1)
        {
            //会有重复添加的值,这里要剪枝
            que.pop();
            continue;
        }
        sum++;
        bitMap[node.first][node.second] = 1;
        if (node.first < m && node.second + 1 < n && bitMap[node.first][node.second + 1] == 0 && is_illegal(node.first, node.second + 1, k))
            que.push(std::make_pair(node.first, node.second + 1));
        if (node.first + 1 < m && node.second < n && bitMap[node.first + 1][node.second] == 0 && is_illegal(node.first + 1, node.second, k))
            que.push(std::make_pair(node.first + 1, node.second));
        que.pop();
    }
}

 

posted @ 2020-12-10 20:47  寅鸷  阅读(100)  评论(0编辑  收藏  举报