インタビューの質問13:ロボットの可動範囲(C ++)

タイトルアドレス:https : //leetcode-cn.com/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof/

タイトルの説明

座標[0,0]から座標[m-1、n-1]まで、地面にm行n列のグリッドがあります。ロボットは座標[0、0]のグリッドから開始し、一度に1つのグリッドを左、右、上、下に移動できます(グリッドの外に移動できません)。また、行と列の座標を入力できません。数字の合計は、 kの格子。たとえば、kが18の場合、3 + 5 + 3 + 7 = 18であるため、ロボットは正方形[35、37]に入ることができます。しかし、3 + 5 + 3 + 8 = 19であるため、正方形[35、38]に入ることができません。ロボットが到達できるグリッドはいくつですか?

質問の例

例1:

入力:m = 2、n = 3、k = 1
出力:3
例2:

入力:m = 3、n = 1、k = 0
出力:1
ヒント:

1 <= n、m <= 100
0 <= k <= 20

問題解決のアイデア

行列検索の問題は、幅優先検索または深さ優先検索戦略によって解決できます。これは、左上隅から右下隅であるため、上下に移動することなく、上下に移動することによってのみ到達できるためです。

ロボットの可動範囲は、次の2つの条件を同時に満たす必要があります。

  • 現在のグリッド座標の数字の合計はk以下です。
  • 座標(0、0)から開始して、現在のグリッドは、上下左右に移動することで到達できます。

BFS:幅優先検索では、キューを使用して問題を解決します。検索されていない各ポイントを一度にキューに入れ、キューの先頭要素を現在通過しているノードとしてポップします。BFSがここにあり、現在までの特定のトラバーサル数を判別する必要がない場合、テンプレートは次のとおりです。

一方、(キューない空きキュー)
    CUR = queue.pop()
     のためのノードCURすべての隣接ノード:
         IF ノードが有効でアクセスされない:
            (ノード)queue.push

現在通過しているレイヤー、つまりステップの数またはバイナリツリーのレベルを判別する必要がある場合、テンプレートは次のとおりです。

レベルlevel = 0 
while (queue queue is not empty)the 
    number of elements in the queue size = queue.size()// the number of nodes to move to 
    while whilesize- ){ 
        cur = queue.pop()
         forノード内の隣接の全ては、CURノード:
             IF ノードがアクセス有効ではない:
                queue.push(ノード)
    } 
層レベル ++。

この問題では、トラバースレイヤーの数を記録する必要はなく、トラバースされたポイントの数を数えるだけで済みます。visitを使用して、ポイントがトラバースされたかどうかを記録します。

DFS:深度优先搜索通过递归,先朝着一个方向搜索到底,再回溯至上个节点,沿另一个方向搜索,依次类推。在本题中,我们用数组visited来存储每个元素是否已被访问,一般的时候,我们是从上下左右四个方向行走,但分析本题可发现,从下和右两个方向前行,所以,我们最后使用dfs(x + 1, y, m, n, k) + dfs(x, y + 1, m, n, k) + 1来返回向下和向右走的数目。需要注意的一点是剪枝条件,在搜索中,遇到数位和超出目标值、此元素已访问,则应立即返回,即可行性剪枝。这里我们剪枝的条件设置为当前节点已被访问或该元素下标溢出,以及行坐标x和列坐标y的数位和(即个位+十位)大于k。

程序源码

BFS

class Solution {
public:
    int visited[100][100];
    int step = 0; 
    int movingCount(int m, int n, int k) {
        for(int i = 0; i < m; i++)
        {
            for(int j = 0; j < n; j++)
            {
                visited[i][j] = 0; //初始化,所有元素均未访问
            }
        }
        queue<pair<int,int>> que;
        que.push({0, 0});
        visited[0][0] = 1; //已访问
        int dir_x[] = {0, 0, -1, 1};  //x方向坐标
    int dir_y[] = {-1, 1, 0, 0};  //y方向坐标
        while(!que.empty())
        {
            auto front = que.front();
            que.pop();
            int x = front.first;
            int y = front.second;
            step++;
            for(int i = 0; i < 4; i++)
            {
                int new_x = x + dir_x[i];
                int new_y = y + dir_y[i];
                if(new_x < 0 || new_y < 0 || visited[new_x][new_y] == 1 || new_x >= m || new_y >= n || (new_x / 10 % 10 + new_x % 10 + new_y / 10 % 10 + new_y % 10) > k) continue;
                que.push({new_x, new_y});
                visited[new_x][new_y] = 1;
            }
        }
        return step;
    }
};

DFS

class Solution {
public:
    int visited[100][100];
    int step = 0; 
    int movingCount(int m, int n, int k) {
        for(int i = 0; i < m; i++)
        {
            for(int j = 0; j < n; j++)
            {
                visited[i][j] = 0; //未访问
            }
        }
        return dfs(0, 0, m, n, k);
    }
    int dfs(int x, int y, int m, int n, int k)
    {
        if(visited[x][y] == 1 || x >= m || y >= n || (x / 10 % 10 + x % 10 + y / 10 % 10 + y % 10) > k) return 0;
        visited[x][y] = 1; //已访问
        step = dfs(x + 1, y, m, n, k) + dfs(x, y + 1, m, n, k) + 1;
        return step;
    }
};

参考文章

https://leetcode-cn.com/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof/solution/c-shi-xian-dfs-he-bfs-by-yun-wang-gui/

おすすめ

転載: www.cnblogs.com/wzw0625/p/12731031.html