【23日出勤を徹底せよ】リートコードの面接質問 01.08. ゼロ行列

CSDN トピック チャレンジ フェーズ 2
参加トピック:アルゴリズム ソリューション

ここに画像の説明を挿入
以前のチェックインレビューの概要:

トピックのリンクと説明

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]
]

キーワード: タグ配列

この質問は中程度の質問としてマークされています。

  1. まず元の 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;
			}
		}
	}

終わり

コメント エリアでのコミュニケーション、毎日チェックイン、お急ぎください。

おすすめ

転載: blog.csdn.net/qq_35530042/article/details/127129242