給你一個矩陣 mat
,其中每一行的元素都已經按 遞增 順序排好了。請你幫忙找出在所有這些行中 最小的公共元素。
如果矩陣中沒有這樣的公共元素,就請返回 -1
。
示例:
輸入:mat = [[1,2,3,4,5],[2,4,5,8,10],[3,5,7,9,11],[1,3,5,7,9]]
輸出:5
提示:
1 <= mat.length, mat[i].length <= 500
1 <= mat[i][j] <= 10^4
mat[i]
已按遞增順序排列。
題解
感覺這題比第二題簡單多了。不明白為什么要分數一樣。
定義一個一維數組表示每行可能是最小公共元素的列下標。然后比較每行的列下標所指的數的是否相等,如果全都相等,說明它就是最小公共元素。
那下標的改變是靠什么呢?
pos[j]
表示第 j
行的當前下標。
如果指向的數比第 0
行的當前數小,那么它就要加 1
,即向后移動。
如果大於,那么說明第 j
行不存在和第 0
行第 i
個數相等的數。即第 i
個數不是最小公共元素。
如果相等就檢查下一行。直到所有行都滿足條件。
時間復雜度: 雙層循環
空間復雜度: 一維數組和 mat
的行數有關,
Java
class Solution {
public int smallestCommonElement(int[][] mat) {
int m = mat.length;
int n = mat[0].length;
int[] pos = new int[m];// 保存每行的可能的最小公共元素的列下標
// 遍歷第0行的n個數
for (int i = 0; i < n; ++i) {
boolean flag = true;// 第0行的第i個數(簡:數x)是最小的公共元素
// 遍歷第1~n行,檢查第0行的第i個數是否在第j行中
for (int j = 1; j < m; ++j) {
// 第j行的數小,那么下標pos[j]后移
while (mat[j][pos[j]] < mat[0][i]) {
if (++pos[j] >= n) {// 第j行已經遍歷完,都不存在數x
return -1;// 直接返回未找到,即-1
}
}
// 第j行的第pos[j]個數大於數x,那么數x不滿足條件
if (mat[j][pos[j]] > mat[0][i]) {
flag = false;// 設為不是
break;// 退出
}
}
if (flag == true) {
return mat[0][i];// 是最小公共元素,返回它
}
}
return -1;// 沒找到
}
}