您的位置:首页 > 其它

[LintCode]找峰值 II

2015-09-21 16:27 309 查看
题目:

一个整数矩阵有如下一些特性:

相邻的整数都是不同的
矩阵有 n 行 m 列。
对于所有的 i < m, 都有 A[0][i] < A[1][i] && A[n - 2][i] > A[n - 1][i].
对于所有的 j < n, 都有 A[j][0] < A[j][1] && A[j][m - 2] > A[j][m - 1].

我们定义一个位置 P 是一个峰,如果有 A[j][i] > A[j+1][i] && A[j][i] > A[j-1][i] && A[j][i] > A[j][i+1] && A[j][i] > A[j][i-1]。

找出该矩阵的一个峰值元素,返回他的坐标。

您在真实的面试中是否遇到过这个题?

Yes

样例

给一个矩阵:
[
[1 ,2 ,3 ,4 ,5],
[16,41,23,22,6],
[15,17,24,21,7],
[14,18,19,20,8],
[13,12,11,10,9]
]

返回 41 的坐标
[1,1]
, 或者 24
的坐标
[2,2]


注意

可能会存在多个峰值,返回任意一个即可。

解答:

解法一,假设当前寻找的位置为(i,j),如果A[i][j]不是峰值,那么选相邻四个元素中最大的那个为下一个寻找的对象。时间复杂度为O(m*n)

代码如下:

class Solution {
/**
* @param A: An integer matrix
* @return: The index of the peak
*/
public List<Integer> findPeakII(int[][] A) {
List<Integer> ans = new ArrayList<Integer>();
int i = 1;
int j = 1;
while(true) {
if(A[i][j] > A[i - 1][j] && A[i][j] > A[i + 1][j] && A[i][j] > A[i][j - 1] && A[i][j] > A[i][j + 1]) {
ans.add(i);
ans.add(j);
return ans;
}
int max = Math.max(Math.max(Math.max(A[i - 1][j], A[i + 1][j]), A[i][j - 1]), A[i][j + 1]);
if(max == A[i - 1][j] && i - 1 > 0) {
i = i - 1;
}
else if(max == A[i + 1][j] && i + 1 < A.length - 1) {
i = i + 1;
}
else if(max == A[i][j - 1] && j - 1 > 0) {
j = j - 1;
}
else if(max == A[i][j + 1] && j + 1 < A[0].length - 1){
j = j + 1;
}
else {
break;
}
}
return ans;
}
}


解答二,用二分查找,横竖都用二分查找,时间复杂度为O(lgm * lgn),也是O(m + n),因为每个元素只可能遍历一遍。

代码如下:

class Solution {
/**
* @param A: An integer matrix
* @return: The index of the peak
*/
public List<Integer> findPeakII(int[][] A) {
List<Integer> ans = new ArrayList<Integer>();
int begin = 0;
int end = A.length - 1;
while(begin <= end) {
int mid = begin + (end - begin) / 2;
int peak = findPeak(A[mid]);
if(A[mid][peak] > A[mid - 1][peak] && A[mid][peak] > A[mid + 1][peak]) {
ans.add(mid);
ans.add(peak);
return ans;
}
else if(A[mid][peak] < A[mid - 1][peak]) {
end = mid - 1;
}
else {
begin = mid + 1;
}
}
return ans;
}

public int findPeak(int[] A) {
int begin = 0;
int end = A.length - 1;
while(begin <= end) {
int mid = begin + (end - begin)/2;
if(mid == 0) {
if(A[mid] > A[mid + 1]) {
return mid;
}
else {
return mid + 1;
}
}
else if(mid == A.length - 1) {
if(A[mid] > A[mid - 1])
return mid;
else
return mid - 1;
}
if(A[mid] > A[mid - 1] && A[mid] > A[mid + 1])
return mid;
else if(A[mid] < A[mid - 1])
end = mid - 1;
else
begin = mid + 1;
}
return begin;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: