一魚再吃 用 二分搜尋 來尋找平面相對高點 Find a Peak Element II_Leetcode #1901

更新於 發佈於 閱讀時間約 5 分鐘

這題的題目在這裡

題目會給定一個2D 二維的矩陣,矩陣內的元素值代表對應的高度,要求我們找出相對最高點,也就是(大樓)高度大於N4 東、南、西、北 四個鄰居的索引值。

題目保證矩陣內相鄰的元素值都不相同,也又是相鄰的兩兩相比較,一定有一個比較高,有一個比較矮。

答案可能不只一組,返回任何一組合法的皆可。

題目要求我們的演算法,必須在O( m log n ) 或者 O( n log m )時間複雜度之內。

註:
其實經驗累積久了,看到m log n 這種order的時間複雜度,就會想到二維平面的二分搜尋法,這是一個很強烈的提示。



測試範例:

Example 1:

raw-image


Input: mat = [[1,4],[3,2]]
Output: [0,1]
Explanation: Both 3 and 4 are peak elements so [1,0] and [0,1] are both acceptable answers.

Example 2:

raw-image


Input: mat = [[10,20,15],[21,30,14],[7,16,32]]
Output: [1,1]
Explanation: Both 30 and 32 are peak elements so [1,1] and [2,2] are both acceptable answers.

約束條件:

Constraints:

  • m == mat.length
  • n == mat[i].length
  • 1 <= m, n <= 500 矩陣一定有內容,保證不是空陣列
  • 1 <= mat[i][j] <= 105
  • No two adjacent cells are equal. 每個相鄰的元素都不同

演算法:

承接一開始題目的限制,也是提示,複雜度必須在O( m log n ) 或者 O( n log m )之內。

一開始先剖半,找到寬度的中心點,從中心點那條column開始找,

接著,在垂直方向找出有最大值的那一個row,再和那個row的左右鄰居做比較。

題目又保證矩陣內相鄰的元素值都不相同,也又是相鄰的兩兩相比較,一定有一個比較高,有一個比較矮。

所以,比較之後,往大的那邊移動(因為我們今天要找的是相對最大值,也就是擁有相對最高的矩陣索引值)

每次砍半,捨去一半不可能的區間,直到找到相對最大值,然後返回該點的索引值,就是答案。


程式碼:

class Solution(object):
 def findPeakGrid(self, mat):

  # height and width of input matrix
  h, w = len(mat), len(mat[0])

  # Window of binary search, initialized as boundary
  left, right = 0, w-1

  # Find largest column by binary search
  while left <= right:

   cur_col = left + ( right - left ) // 2
   
   # Find largest row by brute force linear scan on row-wise
   cur_max = -math.inf
   cur_row = -1
   for row in range(h):
    
    if mat[row][cur_col] > cur_max:
     cur_max = mat[row][cur_col]
     cur_row = row

   # Binary seach to find peak element on column-wise
   leftLarger = (cur_col -1 >= 0) and mat[cur_row][cur_col-1] > mat[cur_row][cur_col]
   rightLarger = (cur_col +1 <= (w-1) ) and mat[cur_row][cur_col+1] > mat[cur_row][cur_col]

   if leftLarger:
    right = cur_col-1

   elif rightLarger:
    left = cur_col+1
    
   else:
    return [cur_row, cur_col]

  return [-1, -1]

 


時間複雜度:

O( h log w ) = O( m log n )

垂直方向找最大值耗費O( m )

內層針對水平方向做二分搜尋法,耗費O( log n )

空間複雜度:

O( 1 ) 只使用固定尺寸的臨時變數,所占用的空間為常數級別O( 1 )


這題學完,記得去複習經典的Binary search
強烈推薦複習這題-> Search a 2D MatrixSqrt(x)Find Peak Element
背後的二分搜尋法原理和對半切從中心點去逼近解答、目標值的想法都是相通的喔!


Reference:

[1] Python O( h log w ) by 2D binary search [w/ Comment] - Find a Peak Element II - LeetCode

avatar-img
91會員
425內容數
由有業界實戰經驗的演算法工程師, 手把手教你建立解題的框架, 一步步寫出高效、清晰易懂的解題答案。 著重在讓讀者啟發思考、理解演算法,熟悉常見的演算法模板。 深入淺出地介紹題目背後所使用的演算法意義,融會貫通演算法與資料結構的應用。 在幾個經典的題目融入一道題目的多種解法,或者同一招解不同的題目,擴展廣度,並加深印象。
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
題目會給定一個陣列,陣列裡面的元素分布就像一座山峰。 最大值的左邊都是上坡段,最大值的右邊都是下坡段。 要求我們找出陣列裡面的絕對極大值(absolute max value)所在的陣列索引
題目會給定一個陣列,裡面有大有小,可以把數字的大小類比成高度 要求我們找出陣列裡面的相對極大值(relative max value)所在的陣列索引 也就是說當下這個元素,大於左邊鄰居的元素值,也大於右邊鄰居的元素值
題目會給定我們一個陣列,並且定義了一種三角形合併的操作。 當下這一排相鄰的兩項相加,對mod 10取餘數,會成為下一排的對應項,一直反覆操作,直到剩下一個元素為止。 要求我們返回最後一層的答案。 測試範例: Example 1: Input: nums = [1,2,
這題的題目在這裡 題目會給定一個輸入整數x, 要求我們返回x的正整數平方根(取無條件捨去小數部分的正整數值)
這題基本上是前一題巴斯卡三角形的孿生題,那題和這題的本質是完全一樣的,只是題目要求稍有不同。 前一題求的是整個巴斯卡三角形,這一題求的是巴斯卡三角形的最後一層。
在學習過比較基本的DP模型 費式數列、爬樓梯、找零錢...等之後, 來看一個比較進階而且實用的DP模型,前綴和(Prefix sum), 可以再加以延伸推廣,來計算 區間和(Range Sum)。
題目會給定一個陣列,陣列裡面的元素分布就像一座山峰。 最大值的左邊都是上坡段,最大值的右邊都是下坡段。 要求我們找出陣列裡面的絕對極大值(absolute max value)所在的陣列索引
題目會給定一個陣列,裡面有大有小,可以把數字的大小類比成高度 要求我們找出陣列裡面的相對極大值(relative max value)所在的陣列索引 也就是說當下這個元素,大於左邊鄰居的元素值,也大於右邊鄰居的元素值
題目會給定我們一個陣列,並且定義了一種三角形合併的操作。 當下這一排相鄰的兩項相加,對mod 10取餘數,會成為下一排的對應項,一直反覆操作,直到剩下一個元素為止。 要求我們返回最後一層的答案。 測試範例: Example 1: Input: nums = [1,2,
這題的題目在這裡 題目會給定一個輸入整數x, 要求我們返回x的正整數平方根(取無條件捨去小數部分的正整數值)
這題基本上是前一題巴斯卡三角形的孿生題,那題和這題的本質是完全一樣的,只是題目要求稍有不同。 前一題求的是整個巴斯卡三角形,這一題求的是巴斯卡三角形的最後一層。
在學習過比較基本的DP模型 費式數列、爬樓梯、找零錢...等之後, 來看一個比較進階而且實用的DP模型,前綴和(Prefix sum), 可以再加以延伸推廣,來計算 區間和(Range Sum)。
你可能也想看
Google News 追蹤
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
高中數學主題練習—求空間中平面
Thumbnail
觀看本文將可以學習到如何利用Numpy求得物件的邊緣點,及算出物件的寬跟高。 有詳細的程式邏輯說明,及各函式用法說明。 綠點及紅點則是採樣到的邊界點,比較粗的點是偵測到的最大值 完整程式碼 import cv2 import numpy as np import matplotl
Thumbnail
去年已閱讀了《底層邏輯》,整本書也是貼滿了標籤貼,值得閱讀的一本。 底層邏輯2,用了很多數學計算公式來讓我們知道萬物運作的本質,並運用於商業模式上,讓創業者在創業的路上提高成功的機率。我覺得這本書需慢慢細讀,作者劉潤的舉例也盡量很淺白易懂,因為大部分的人對數學總是害怕。雖然不需要懂其中計算方式,但
Thumbnail
《底層邏輯》在【超閱讀觀點83】有介紹過,西恩之所以要把《底層邏輯2》再隔兩本介紹,主要原因在於,這本書是以許多人聞之色變的「數學」出發,把我們會遇到的「現象」用數學解釋,所以基本上,相較於《底層邏輯》的高易讀性,《底層邏輯2》顯然沒辦法讀那麼快,且更需要思考,不過能得到的收穫也更多。 《底層邏輯
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
高中數學主題練習—求空間中平面
Thumbnail
觀看本文將可以學習到如何利用Numpy求得物件的邊緣點,及算出物件的寬跟高。 有詳細的程式邏輯說明,及各函式用法說明。 綠點及紅點則是採樣到的邊界點,比較粗的點是偵測到的最大值 完整程式碼 import cv2 import numpy as np import matplotl
Thumbnail
去年已閱讀了《底層邏輯》,整本書也是貼滿了標籤貼,值得閱讀的一本。 底層邏輯2,用了很多數學計算公式來讓我們知道萬物運作的本質,並運用於商業模式上,讓創業者在創業的路上提高成功的機率。我覺得這本書需慢慢細讀,作者劉潤的舉例也盡量很淺白易懂,因為大部分的人對數學總是害怕。雖然不需要懂其中計算方式,但
Thumbnail
《底層邏輯》在【超閱讀觀點83】有介紹過,西恩之所以要把《底層邏輯2》再隔兩本介紹,主要原因在於,這本書是以許多人聞之色變的「數學」出發,把我們會遇到的「現象」用數學解釋,所以基本上,相較於《底層邏輯》的高易讀性,《底層邏輯2》顯然沒辦法讀那麼快,且更需要思考,不過能得到的收穫也更多。 《底層邏輯