1. 程式人生 > >程式設計師面試金典1.7:若M*N矩陣中某個元素為0,則將其所在的行與列清零

程式設計師面試金典1.7:若M*N矩陣中某個元素為0,則將其所在的行與列清零

1.7:編寫一個演算法,若M*N矩陣中某個元素為0,則將其所在的行與列清零。

咋一看,這個問題很簡單:直接遍歷整個矩陣,只要發現值為0的元素,就將其所在的行與列清零。不過這種方法有個缺陷:在讀取被清零的行與列時,讀到的盡是零,於是所在的行與所在的列都變成了0,很快,整個矩陣都變成了0.

避開這個缺陷的方法之一是新建一個矩陣標記零元素的位置。然後,在第二遍遍歷矩陣的時候將0元素所在的行與列清零。這種做法的空間複雜度為O(MN)

真的需要佔用O(MN)空間嗎?不是的,既然打算將整行和整列清零,因此並不需要標記錄它是cell[2][4](行2,列4),只需要知道行2有個元素為0,列4有個元素為0.不管怎樣,整行和整列都要清零,又何必要記錄零元素的確切位置?

下面這個演算法的實現程式碼。這裡用兩個陣列分別記錄包含零元素的所在行和列,然後,在第二遍遍歷矩陣時,若所在行或所在列標記為0,則將元素清為0

public void setZeros(int[][] matrix){
		boolean[] row = new boolean[matrix.length];
		boolean[] column = new boolean[matrix[0].length];
		
		//記錄值為0的元素所在行索引和列索引
		for(int i = 0;i<matrix.length;i++){
			for(int j = 0;j<matrix[0].length;j++){
				if(matrix[i][j] == 0){
					row[i] = true;
					column[j] = true;
				}
			}
		}
		//若行i或列j有個元素為0,則將arr[i][j] 置為0
		for(int i = 0;i<matrix.length;i++){
			for(int j = 0;j<matrix[0].length;j++){
				if(row[i]|| column[j]){
					matrix[i][j] =0;
				}
			}
		}
		print(matrix);
	}