CSDN トピック チャレンジ フェーズ 2
参加トピック:アルゴリズム ソリューション
記事ディレクトリ
以前のチェックインレビューの概要:
- ちなみに、初日のグラフのノード パス dfs と bfs については、グラフの関連概念を確認してください。
- 2日目は単語間のスペースを並べ替える模擬問題
- 3 日目の速いポインターと遅いポインター、数字の再編成
- 4日目も誘導質問、美しい行列
- 5日目 動的計画法、最長固定差分数列
- 6 日目には、バイナリ ツリーを構築し、ツリーの走査を確認します。
- 7日目、労働者に勝つ、k人の最低コストの問題
- 8日目、二分探索、配列固有値
- 9日目、貪欲なアルゴリズム、最大の交換
- 11日目、真理値表、パターンの発見、電球のスイッチ
- 12 日目、最初の接触スキャン ライン、カバーされた領域
- 13 日目、スライディング ウィンドウ、ハッシュ テーブル、同じ文字間の最長の文字列
- 15日目、マトリックス、ハッシュテーブル、人工島
- 16 日目、枝刈り、再帰、k 個の等しいサブセットの検索
- 18日目もハッシュテーブル、配列に接続できるかどうか
- 20日目、XOR、総和、インプレースハッシュの3つの手法で2桁消滅を目指す
- 21日目、ハッシュテーブル、並べ替え、文字並べ替え
- 22日目、文字マッチング、文字列ローテーション
トピックのリンクと説明
M × N 行列の要素が 0 である行と列をクリアするアルゴリズムを作成します。
例 1:
入力:
[
[1,1,1]、
[1,0,1]、
[1,1,1]
]
出力:
[
[1,0,1]、
[0,0,0]、
[1,0] ,1]
]
例 2:
入力:
[
[0,1,2,0]、
[3,4,5,2]、
[1,3,1,5]
]
出力:
[
[0,0,0,0]、
[0,4] ,5,0]、
[0,3,1,0]
]
キーワード: タグ配列
この質問は中程度の質問としてマークされています。
- まず元の 0 値の位置を保存することを検討し、次に水平値と垂直値を 0 に設定します。
方法 1: 配列 mn をマークする
スクリーンショットを実行する
コード
public void setZeroes(int[][] matrix) {
boolean[][] zero = new boolean[matrix.length][matrix[0].length];
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
zero[i][j] = matrix[i][j] == 0;
}
}
for (int i = zero.length - 1; i >= 0; i--) {
for (int j = zero[i].length - 1; j >= 0; j--) {
if (zero[i][j]) {
setZeroesXY(matrix, i, j);
}
}
}
}
private void setZeroesXY(int[][] matrix, int i, int j) {
for (int i1 = matrix.length - 1; i1 >= 0; i1--) {
matrix[i1][j] = 0;
}
for (int j1 = matrix[i].length - 1; j1 >= 0; j1--) {
matrix[i][j1] = 0;
}
}
方法 2: m + n の複雑さ
スパース グラフと同様に、mxn 行列を使用すると多くのスペースが無駄になります。必要なのは 1 行または 1 列だけです。同時に、トラバースする場合、行と列に 0 があれば十分です。
スクリーンショットを実行する
コード
public void setZeroes(int[][] matrix) {
boolean[] row = new boolean[matrix.length];
boolean[] col = new boolean[matrix[0].length];
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
if (matrix[i][j] == 0) {
row[i] = col[j] = true;
}
}
}
for (int i = matrix.length - 1; i >= 0; i--) {
for (int j = matrix[i].length - 1; j >= 0; j--) {
if (col[j] || row[i]) {
matrix[i][j] = 0;
}
}
}
}
方法 3: 空間計算量 1、時間計算量 mn
問題の解決策を見始めましたが、最初は理解できませんでした。中程度の難易度もここにあるかもしれません。実装は簡単ですが、それに対応する時間と空間の複雑さを想像するのは困難です。
このアイデアは、削除する行と列を使用し、行列の 0 ビットを使用して削除されたかどうかを保存することで、m+n のスペースを節約します。先頭が 0 ビットの場合、対応する行と列をさらに処理する必要があります。
スクリーンショットを実行する
コード
public void setZeroes(int[][] matrix) {
int n = matrix.length, m = matrix[0].length;
// 起始0位是否有0
boolean row0 = false;
boolean col0 = false;
for (int i = 0; i < n; i++) {
if (matrix[i][0] == 0) {
col0 = true;
break;
}
}
for (int j = 0; j < m; j++) {
if (matrix[0][j] == 0) {
row0 = true;
break;
}
}
// 从1位开始,归拢到0位
for (int i = 1; i < n; i++) {
for (int j = 1; j < m; j++) {
if (matrix[i][j] == 0) {
matrix[0][j] = matrix[i][0] = 0;
}
}
}
// 开始遍历1判断是否需要消除
for (int i = 1; i < n; i++) {
for (int j = 1; j < m; j++) {
if (matrix[0][j] == 0 || matrix[i][0] == 0) {
matrix[i][j] = 0;
}
}
}
if (col0) {
for (int i = 0; i < n; i++) {
matrix[i][0] = 0;
}
}
if (row0) {
for (int i = 0; i < m; i++) {
matrix[0][i] = 0;
}
}
}
終わり
コメント エリアでのコミュニケーション、毎日チェックイン、お急ぎください。!!