[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
样例
给一个矩阵:
返回 41 的坐标
的坐标
注意
可能会存在多个峰值,返回任意一个即可。
解答:
解法一,假设当前寻找的位置为(i,j),如果A[i][j]不是峰值,那么选相邻四个元素中最大的那个为下一个寻找的对象。时间复杂度为O(m*n)
代码如下:
解答二,用二分查找,横竖都用二分查找,时间复杂度为O(lgm * lgn),也是O(m + n),因为每个元素只可能遍历一遍。
代码如下:
一个整数矩阵有如下一些特性:
相邻的整数都是不同的
矩阵有 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; } }
相关文章推荐
- Java中的队列:java.util.Queue接口
- XE8-indy10中TIdTCPClient控件Disconnect源码分析
- Android 开发环境下载地址 -- 百度网盘 adt-bundle android-studio sdk adt 下载
- openfire插件开发之完美开发
- cxf发布和调用webservice
- 本土化手机游戏需要考虑的10种语言
- Java解析Json对象
- Docker数据管理
- 图的深度优先搜索和广度优先搜索
- hdu 5464 Clarke and problem dp
- bootstrap 学习
- JVM调优总结-调优方法
- Linux下清理内存和Cache方法
- jQuery实现Tab菜单滚动切换的方法
- 第三周项目1-顺序表的基本运算(2)
- 使用ACEGI搭建权限系统
- smart_iceboy的开博声明,合并之前的qq43068902与xciceboy两个csdn的博客
- 一篇很全面的freemarker教程
- hadoop 权威指南【第三版】
- Android 解决 ScrollView嵌套ListView、GridView冲突显示不全的最快实现