レイコウ問題解決策:542問題01マトリックス知識ポイント:最短距離を見つけるために使用されるマルチソースBFS(現在のトラバーサルレベルを決定するか、2種類のテンプレートではない)

1.タイトルの説明:タイトルリンク
0と1で構成される行列が与えられた場合、各要素と最も近い0の間の距離を調べます。
2つの隣接する要素間の距離は1です。
例1:
入力:
0 0 0
0 1 0
0 0 0
出力:
0 0 0
0 1 0
0 0 0
注:
指定された行列の要素数は10,000を超えません。
与えられた行列の少なくとも1つの要素は0です。
マトリックスの要素は、上下左右の4方向にのみ隣接しています。

2.アイデア:調査するトピックが何であるかを理解し、残りのタスクはテンプレートを設定することです!
a)最初に見るマトリックス上の距離を検索し、グラフの解について考えます。
b)この質問はシナリオを与えます:1から0までの最短距離を見つけます。グラフで、ポイントから最短距離見つける方法はBFSと考えるのが簡単です、つまり、周囲の円を検索した後、次の円を検索します。これは、検索範囲を徐々に拡大することです。

2.1。BFSテンプレート:
BFSはキューを使用し、検索されていない各ポイントを順番にキューに配置してから、キューの先頭要素を現在のトラバースポイントとしてポップします。BFSには合計で2つのテンプレートが
あります。a)現在トラバースされているレベルを判別する必要がない場合、BFSテンプレートは次のようになります。

while queue 不空:
    cur = queue.pop()
    for 节点 in cur的所有相邻节点:
        if 该节点有效且未访问过:
            queue.push(该节点)

b)現在通過しているレイヤーを特定する場合、BFSテンプレートは次のとおり
です。追加されたレベルは、現在横断されているバイナリツリーのレベルを示します。これは、グラフで実行されたステップ数としても理解できます。サイズは、現在のトラバーサルレイヤーにある要素の数、つまりキュー内の要素の数を示します。これらの要素を一度にトラバースします。つまり、現在のレイヤーのすべての要素を1ステップ外側に移動します。

level = 0
while queue 不空:
    size = queue.size() // 记录当前层次
    while (size --) {
    
    
        cur = queue.pop()
        for 节点 in cur的所有相邻节点:
            if 该节点有效且未被访问过:
                queue.push(该节点)
    }
    level ++;

上記の2つは一般的なテンプレートであり、どのトピックでも使用できます。覚えておいてください。
リンクのアイデア、作者:fuxuemingzhu

3.マルチソースBFSとシングルソースBFSの違い:
3.1。アイデア:

  • ために 「ツリーのBFS」(典型的な「単一ソースBFS」)誰もがすでに
    道路に精通しています最初にルートノードをチームに入力し、次に何も考えずにレイヤーごとにトラバースします。
  • ために 「グラフィックBFS」(「マルチソースBFS」)、そして「ツリーのBFS」の違いは次の2つに注意してください。
    ツリーには1つのルートしかなく、グラフは複数のソースを持つことができるため、まず、複数のソースをエンキューする必要があります;
    ツリーは方向付けられているため、アクセスされたかどうかを識別する必要はありません。無向グラフの場合、訪問されたかどうかをマークする必要があります!また、特定のノードが複数回チームに入るのを防ぐには、チームに入る前に、訪問済みとして設定する必要があります。
    リンクのアイデア、作者:sweetiee

3.2。ソース検索:

  • ツリーの場合:
    ソースポイントはツリーのルートです。
  • グラフの場合:グラフ
    のトラバーサルはいつでも開始できますが、マルチソースの問題の場合、最初にすべての頂点をトラバースして、すべてのソースポイントがキューにプッシュされていることを確認します。

4. C ++コード:
コードは自分の考えを記録するためのものであり、時間の複雑さとスペースの複雑さは最適ではありません。最適なコードについては、上記の2つのリンクを参照してください。

class Solution {
    
    
public:
    vector<vector<int>> updateMatrix(vector<vector<int>>& matrix) {
    
    
        int row = matrix.size();
        int col = matrix[0].size();
        vector<vector<int>> res(row,vector<int>(col)); //记录结果
        vector<vector<int>> visited(row,vector<int>(col)); // 记录访问情况
        queue<pair<int,int>> q;
        for(int i = 0;i<row; i++){
    
     //首先查找所有源点
            for(int j = 0;j<col; j++){
    
    
                if(matrix[i][j] == 0){
    
                       
                    q.push(make_pair(i,j));
                    visited[i][j] = 1;
                }
            }
        }
        int val = 0; // 记录遍历层次
        while(!q.empty()){
    
    
            int size = q.size(); //记录每一层元素个数
            for(int i = 0;i<size;i++){
    
    
                pair<int, int> tmp = q.front();
                q.pop();
                res[tmp.first][tmp.second] = val;
                if(tmp.first-1>=0 && visited[tmp.first-1][tmp.second] == 0){
    
    
                    q.push(make_pair(tmp.first-1,tmp.second));
                    visited[tmp.first-1][tmp.second] = 1;
                }
                if(tmp.first+1<row && visited[tmp.first+1][tmp.second] == 0){
    
    
                    q.push(make_pair(tmp.first+1,tmp.second));
                    visited[tmp.first+1][tmp.second] = 1;
                }
                if(tmp.second-1>=0 && visited[tmp.first][tmp.second-1] == 0){
    
    
                    q.push(make_pair(tmp.first,tmp.second-1));
                    visited[tmp.first][tmp.second-1] = 1;
                }
                if(tmp.second+1<col && visited[tmp.first][tmp.second+1] == 0){
    
    
                    q.push(make_pair(tmp.first,tmp.second+1));
                    visited[tmp.first][tmp.second+1] = 1;
                }
            }
            val++;
        }
        return res;
    }
};

総括する:

1.距離を見つけることは、一般的にグラフの問題です。グラフの解について考えてください。
2.通常、最短距離はBFSによって解決されます。
3.マルチソースBFSは最初にすべてのソースポイントを見つけます。
4.現在のトラバーサルレベルを決定する上記のBFSメソッドを思い出してください。

おすすめ

転載: blog.csdn.net/qq_33726635/article/details/106452806
おすすめ