LeetCode 5071. 找出所有行中最小公共元素(Java)


题目:5071. 找出所有行中最小公共元素

给你一个矩阵 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 个数不是最小公共元素。
如果相等就检查下一行。直到所有行都满足条件。

时间复杂度: 双层循环 O(n2)O(n^{2})
空间复杂度: 一维数组和 mat 的行数有关,O(n)O(n)

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;// 没找到
	}
}
posted @ 2019-09-22 16:34  wowpH  阅读(2668)  评论(0编辑  收藏  举报