这是一个谷歌面试问题。
您将获得一个包含N行和N列的矩阵。矩阵中的元素可以是1或0.矩阵的每一行和每列按升序排序。在给定矩阵中找出0-s的数量。
我提出了O(n)解决方案,但根本无法提供O(logn)解决方案。任何指针都非常受欢迎。
编辑:似乎O(logn)似乎不可能,如下所述。
答案 0 :(得分:2)
首先,这是一个算法计算 O(n)时间内的零:
countZeroes(matrix):
n = matrix.rowCount
i = 0
j = n-1
count = 0
while i < n && j >=0:
if matrix[i][j] == 1 then:
j--
else:
i++
count += j+1
return count
每次迭代都会增加 i 或减少 j ,并且两者都只能在循环之前取 0..n-1 之间的值结束,最大迭代次数为 2n ,即 O(n)。
这是一个JavaScript代码段,可生成5x5随机矩阵,并使用上述算法对零进行计数:
function countZeroes(matrix) {
var n = matrix.length,
i = 0,
j = n-1,
count = 0;
while (i < n && j >=0) {
if (matrix[i][j] === 1) {
j--;
} else {
i++;
count += j+1;
}
}
return count;
}
function randomMatrix(n) {
var matrix = [],
zeroCounts = [];
for (var i = 0; i < n; i++) {
zeroCounts[i] = Math.floor(Math.random() * (n+1));
}
zeroCounts.sort((a,b) => b-a); // descending
for (var i = 0; i < n; i++) {
matrix[i] = [];
for (var j = 0; j < n; j++) {
matrix[i][j] = j < zeroCounts[i] ? 0 : 1;
}
}
return matrix;
}
function matrixToString(matrix) {
var s = '';
for (var i = 0; i < matrix.length; i++) {
s += matrix[i].join('') + '\n';
}
return s;
}
var matrix = randomMatrix(5);
console.log(matrixToString(matrix));
console.log('Zeroes: ', countZeroes(matrix));
想象一下像这样的矩阵:
0000
0001
0011
0111
您需要访问此矩阵中的每一行才能知道其中有多少个零。想象一下,你只会访问4行中的3行:它可能是任何3行...除非你也访问第4行,否则至少有3个可能的结果为零。
例如,如果您访问过第0行,第1行和第3行,您就会知道:
0000
0001
****
0111
通过对行和列进行排序,您可以扣除:
0000
0001
0**1
0111
但剩余的**
可以是00
,01
或11
。找出答案的唯一方法是实际查看该行中的至少一个值。
结论:在 O(n)之内不可能。
答案 1 :(得分:1)
让我们说在算法过程中我们已经知道矩阵具有以下形式:
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<script>
myFunction()
function myFunction() {
var a="Qt: joe: this is test text1";
var b="Qt: bella: this is test text2";
var c="this is test text3";
var d="Qt: alex: this is test text4";
removetxt(a);
removetxt(b);
removetxt(c);
removetxt(d);
}
function removetxt(x) {
var x1 = x.replace(/^(Qt:.*:)/g,"");
alert(x1);
}
</script>
</body>
</html>
我们无法学习任何价值?从任何其他的价值?,所以我们需要看看他们中的每一个。因此,对一般问题的任何解决方案至少需要O( n )时间,以及log( n )或log²( n )中的解决方案)时间是不可能的。
答案 2 :(得分:0)
使用二进制搜索来查找一行中的零数可以帮到这里!
public static int findZerosV2(int[][] NxNMatrix) {
int numZeros = 0;
for (int i = 0; i < NxNMatrix.length; i++) {
int numZerosInRow = binarySearch(NxNMatrix[i]);
if (numZerosInRow > -1) {
numZeros += numZerosInRow;
}
}
return numZeros;
}
public static int binarySearch(int[] rowItem) {
int foundZeros = -1;
int rowIndex = 0;
int highIndex = rowItem.length;
for (int i = 0; i < rowItem.length; i++) {
//find the middle element
int mIndex = (rowIndex + highIndex) / 2;
if (rowItem[mIndex] == 0) {
rowIndex = mIndex + 1;
//keep count using index number of 0
foundZeros = mIndex;
} else
highIndex = mIndex - 1;
}
//considering zero based index array
return foundZeros + 1;
}
答案 3 :(得分:-1)
您可以在每一行上使用二进制搜索来查找0更改为1的位置。 Binarysearch正在处理O(log n)中的排序数组。你会得到改变位置的索引号。你应该为每一行(n次)做,然后时间将是O(n * log n)
答案 4 :(得分:-1)
二进制搜索&#34;中间&#34;在反对角线上指向,然后你就会知道左上角的子矩阵满0,右下角则满1.左下和右下子矩阵的递归搜索? / p>