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メソッドを思い出してください。