1、题目描述
2、解题思路
从第 0 行的左到右依次当成 target ,然后从下列每一行查找这个 targer 是否存在。
比如一个二位数组如下:
拿第 0 行的第一个数字作为 target,然后从下面每一行进行二分查找,是否存在 target:
发现第 1 行就不存在这个 target,肯定不符合条件,于是拿 3 作为 target:
以此类推,直到拿到 7 ,才发现每一行都有:
于是这个 7 就是公共元素,且是最小的那个,因为第 0 行 7 以前没有公共元素。
3、解题代码
class Solution {
public int smallestCommonElement(int[][] mat) {
int n = mat.length, m = mat[0].length;
int[] pos = new int[n]; // 用于保存上一次遍历到的位置
for (int j = 0; j < m; ++j) { // 遍历第 0 行的每一个元素
boolean found = true;
// 遍历 1 到 n-1 行,从每一行找目标值 mat[0][j]
// 如果某一行找不到 mat[0][j] 这个值,则 found 为 false,不用找下面行,目标值更新为 mat[0][j+1],重新遍历 1 到 n-1 行
for (int i = 1; i < n && found; ++i) {
// 使用二分查找,从第 i 行的 [pos[i], m] 区间寻找目标值 mar[0][j]
// 找到了返回索引,找不到则返回 -1
pos[i] = Arrays.binarySearch(mat[i], pos[i], m, mat[0][j]);
if (pos[i] < 0) { // pos[i] = -1
// 如果找不到,则把 found 置 false
found = false;
// 因为已经丢掉第 i 行上一次遍历的位置,所以它下次从 0 开始
pos[i] = 0;
}
}
// 走到这一步,说明 1 到 n-1 行都二分查找完毕
// 如果此时 found 为 true,说明找到了答案
if (found) {
return mat[0][j];
}
}
// 没有答案
return -1;
}
}