有序矩阵元素查找LeetCode简单题
已知int一个有序矩阵mat,同时给定矩阵的大小n和m以及需要查找的元素x,且矩阵的行和列都是从小到大有序的。设计查找算法返回所查找元素的二元数组,代表该元素的行号和列号(均从零开始)。保证元素互异。
数据范围:0 le n,m le 10000≤n,m≤1000,矩阵中的任何元素满足 0 < mat_{i,j} le 10000000<mati,j≤1000000
要求:空间复杂度 O(1)O(1),时间复杂度 O(n+m)O(n+m)
示例1
输入:
[[1,2,3],[4,5,6]],2,3,6
返回值:
[1,2]
示例2
输入:
[[1,2,3]],1,3,2
返回值: [0,1]
一、贪心算法
class Solution { public: vector<int> findElement(vector<vector<int> > mat, int n, int m, int x) { // write code here int i = n-1, j = 0; while(i >= 0 && j < m){ if(mat[i][j] > x) i--; else if(mat[i][j] < x) j++; else return vector<int>({i,j}); } return vector<int>({0,0}); } };
如果当前位置的数大于目标值,根据该矩阵的特性,其右边的数只可能更大,故往上走一步;如果当前位置的数小于目标值,上边的数只可能更小,故往右走一步。
时间复杂度: O(n+m),因为遍历过程中,只是往上和右走,最坏的情况走n+m步走到边上,所以最慢的复杂度是n+m;空间复杂度: O(1)。
二、二分法
class Solution { public: vector<int> findElement(vector<vector<int> > mat, int n, int m, int x) { // write code here for(int i = 0; i < n; i++){ if(mat[i][0] > x || mat[i][m-1] < x) continue; int l = 0, r = m-1; while(l <= r){ int mid = (l+r) >> 1; if(mat[i][mid] > x) r = mid-1; else if(mat[i][mid] < x) l = mid+1; else return vector<int>({i,mid}); } } return vector<int>({0,0}); } };
先排除不可能存在x的行,再逐行二分查找。
时间复杂度: O(nlogm). 遍历过程中, 每一行都对长度为m的数组二分搜索了一次;空间复杂度: O(1)。
下一篇:
算法题-跳格子有多少种走法