zoukankan      html  css  js  c++  java
  • [LintCode] Find Peak Element II

    There is an integer matrix which has the following features:

    1. The numbers in adjacent positions are different.
    2. The matrix has n rows and m columns.
    3. For all i < m, A[0][i] < A[1][i] && A[n - 2][i] > A[n - 1][i].
    4. For all j < n, A[j][0] < A[j][1] && A[j][m - 2] > A[j][m - 1].

    We define a position P is a peek if 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].

    Find a peak element in this matrix. Return the index of the peak.

    Example

    Given a matrix:

    [
      [1 ,2 ,3 ,6 ,5],
      [16,41,23,22,6],
      [15,17,24,21,7],
      [14,18,19,20,10],
      [13,14,11,10,9]
    ]
    

    return index of 41 (which is [1,1]) or index of 24 (which is [2,2])

    Note

    The matrix may contains multiple peeks, find any of them.

    Challenge

    Solve it in O(n+m) time.

    If you come up with an algorithm that you thought it is O(n log m) or O(m log n), can you prove it is actually O(n+m) or propose a similar but O(n+m) algorithm?

    http://www.lintcode.com/en/problem/find-peak-element-ii/

    二分查找!

     1 class Solution {
     2 public:
     3     /**
     4      * @param A: An integer matrix
     5      * @return: The index of the peak
     6      */
     7     vector<int> findPeakII(vector<vector<int> > A) {
     8         // write your code here
     9         vector<int> res;
    10         int left = 0, right = A.size() - 1;
    11         while (left <= right) {
    12             int mid = left + ((right - left) >> 1);
    13             int col = findPeak(A[mid]);
    14             if (A[mid][col] < A[mid+1][col]) {
    15                 left = mid + 1;
    16             } else if (A[mid][col] < A[mid-1][col]) {
    17                 right = mid - 1;
    18             } else {
    19                 return {mid, col};
    20             }
    21         }
    22         return res;
    23     }
    24     int findPeak(vector<int> &v) {
    25         int res = 0;
    26         for (int i = 1; i < v.size(); ++i) {
    27             if (v[i] > v[res]) res = i;
    28         }
    29         return res;
    30     }
    31 };

    下面是错误的,但是居然AC了,数据好弱啊。

    这题跟杨氏矩阵有点像,可以使用杨氏矩阵的思想,因为题目已经说时了第二行第二列倒数第二行倒数第二列肯定比第一行第一列倒数第一行倒数第一列的元素大,那么我们只需从第二行第二列开始寻找,因为要找peek element,所以要跟四周元素比较,如果发现有比它大的元素,那么就移动到比它大的元素的坐标。如果有右侧与下侧都比它大,那么就移到更大的那一个元素那儿,这样就可以保证下一个比当前元素大的元素只可能出现在右侧或下侧。因为我们只会向右或向下移动,所以最坏的情况就是移动到右下角,但时间复杂度还是O(N+M)。

     1 class Solution {
     2 public:
     3     /**
     4      * @param A: An integer matrix
     5      * @return: The index of the peak
     6      */
     7     bool isOK(vector<vector<int> > &A, int i, int j) {
     8         if (i < 1 || i >= A.size() - 1 || j < 1 || j >= A[0].size() - 1) 
     9             return false;
    10         return A[i][j] > A[i][j-1] && A[i][j] > A[i-1][j] 
    11                 && A[i][j] > A[i][j+1] && A[i][j] > A[i+1][j];
    12     }
    13     
    14     vector<int> findPeakII(vector<vector<int> > A) {
    15         // write your code here
    16         vector<int> res;
    17         int i = 1, j = 1;
    18         while (i < A.size() - 1 && j < A[0].size() - 1) {
    19             if (isOK(A, i, j)) {
    20                 res.push_back(i);
    21                 res.push_back(j);
    22                 return res;
    23             } else {
    24                 if (A[i+1][j] > A[i][j+1]) ++i;
    25                 else ++j;
    26             }
    27         }
    28         return res;
    29     }
    30 };
  • 相关阅读:
    python--函数的返回值、函数的参数
    python--字典,解包
    Vue--ElementUI实现头部组件和左侧组件效果
    Vue--整体页面布局
    jmeter--non GUI
    python--切片,字符串操作
    celery--调用异步任务的三种方法和task参数
    celery--实现异步任务
    celery--介绍
    开发问题记录
  • 原文地址:https://www.cnblogs.com/easonliu/p/4509505.html
Copyright © 2011-2022 走看看