|
46 | 46 |
|
47 | 47 | ## Solutions
|
48 | 48 |
|
| 49 | +**Solution 1: Binary Search** |
| 50 | + |
| 51 | +Let $m$ and $n$ be the number of rows and columns of the matrix, respectively. |
| 52 | + |
| 53 | +The problem asks us to find a peak, and the time complexity should be $O(m \times \log n)$ or $O(n \times \log m)$. Therefore, we can consider using binary search. |
| 54 | + |
| 55 | +We consider the maximum value of the $i$-th row, and denote its index as $j$. |
| 56 | + |
| 57 | +If $mat[i][j] > mat[i + 1][j]$, then there must be a peak in the rows $[0,..i]$. We only need to find the maximum value in these rows. Similarly, if $mat[i][j] < mat[i + 1][j]$, then there must be a peak in the rows $[i + 1,..m - 1]$. We only need to find the maximum value in these rows. |
| 58 | + |
| 59 | +Why is the above method correct? We can prove it by contradiction. |
| 60 | + |
| 61 | +If $mat[i][j] > mat[i + 1][j]$, suppose there is no peak in the rows $[0,..i]$. Then $mat[i][j]$ is not a peak. Since $mat[i][j]$ is the maximum value of the $i$-th row, and $mat[i][j] > mat[i + 1][j]$, then $mat[i][j] < mat[i - 1][j]$. We continue to consider from the $(i - 1)$-th row upwards, and the maximum value of each row is less than the maximum value of the previous row. When we traverse to $i = 0$, since all elements in the matrix are positive integers, and the values of the cells around the matrix are $-1$. Therefore, at the 0-th row, its maximum value is greater than all its adjacent elements, so the maximum value of the 0-th row is a peak, which contradicts the assumption. Therefore, there must be a peak in the rows $[0,..i]$. |
| 62 | + |
| 63 | +For the case where $mat[i][j] < mat[i + 1][j]$, we can prove in a similar way that there must be a peak in the rows $[i + 1,..m - 1]$. |
| 64 | + |
| 65 | +Therefore, we can use binary search to find the peak. |
| 66 | + |
| 67 | +We perform binary search on the rows of the matrix, initially with the search boundaries $l = 0$, $r = m - 1$. Each time, we find the middle row $mid$ and find the index $j$ of the maximum value of this row. If $mat[mid][j] > mat[mid + 1][j]$, then we search for the peak in the rows $[0,..mid]$, i.e., update $r = mid$. Otherwise, we search for the peak in the rows $[mid + 1,..m - 1]$, i.e., update $l = mid + 1$. When $l = r$, we find the position $[l, j_l]$ of the peak, where $j_l$ is the index of the maximum value of the $l$-th row. |
| 68 | + |
| 69 | +The time complexity is $O(n \times \log m)$, where $m$ and $n$ are the number of rows and columns of the matrix, respectively. The time complexity of binary search is $O(\log m)$, and each time we perform binary search, we need to traverse all elements of the $mid$-th row, with a time complexity of $O(n)$. The space complexity is $O(1)$. |
| 70 | + |
49 | 71 | <!-- tabs:start -->
|
50 | 72 |
|
51 | 73 | ### **Python3**
|
52 | 74 |
|
53 | 75 | ```python
|
54 |
| - |
| 76 | +class Solution: |
| 77 | + def findPeakGrid(self, mat: List[List[int]]) -> List[int]: |
| 78 | + l, r = 0, len(mat) - 1 |
| 79 | + while l < r: |
| 80 | + mid = (l + r) >> 1 |
| 81 | + j = mat[mid].index(max(mat[mid])) |
| 82 | + if mat[mid][j] > mat[mid + 1][j]: |
| 83 | + r = mid |
| 84 | + else: |
| 85 | + l = mid + 1 |
| 86 | + return [l, mat[l].index(max(mat[l]))] |
55 | 87 | ```
|
56 | 88 |
|
57 | 89 | ### **Java**
|
58 | 90 |
|
59 | 91 | ```java
|
| 92 | +class Solution { |
| 93 | + public int[] findPeakGrid(int[][] mat) { |
| 94 | + int l = 0, r = mat.length - 1; |
| 95 | + int n = mat[0].length; |
| 96 | + while (l < r) { |
| 97 | + int mid = (l + r) >> 1; |
| 98 | + int j = maxPos(mat[mid]); |
| 99 | + if (mat[mid][j] > mat[mid + 1][j]) { |
| 100 | + r = mid; |
| 101 | + } else { |
| 102 | + l = mid + 1; |
| 103 | + } |
| 104 | + } |
| 105 | + return new int[] {l, maxPos(mat[l])}; |
| 106 | + } |
| 107 | + |
| 108 | + private int maxPos(int[] arr) { |
| 109 | + int j = 0; |
| 110 | + for (int i = 1; i < arr.length; ++i) { |
| 111 | + if (arr[j] < arr[i]) { |
| 112 | + j = i; |
| 113 | + } |
| 114 | + } |
| 115 | + return j; |
| 116 | + } |
| 117 | +} |
| 118 | +``` |
| 119 | + |
| 120 | +### **C++** |
| 121 | + |
| 122 | +```cpp |
| 123 | +class Solution { |
| 124 | +public: |
| 125 | + vector<int> findPeakGrid(vector<vector<int>>& mat) { |
| 126 | + int l = 0, r = mat.size() - 1; |
| 127 | + while (l < r) { |
| 128 | + int mid = (l + r) >> 1; |
| 129 | + int j = distance(mat[mid].begin(), max_element(mat[mid].begin(), mat[mid].end())); |
| 130 | + if (mat[mid][j] > mat[mid + 1][j]) { |
| 131 | + r = mid; |
| 132 | + } else { |
| 133 | + l = mid + 1; |
| 134 | + } |
| 135 | + } |
| 136 | + int j = distance(mat[l].begin(), max_element(mat[l].begin(), mat[l].end())); |
| 137 | + return {l, j}; |
| 138 | + } |
| 139 | +}; |
| 140 | +``` |
| 141 | +
|
| 142 | +### **Go** |
| 143 | +
|
| 144 | +```go |
| 145 | +func findPeakGrid(mat [][]int) []int { |
| 146 | + maxPos := func(arr []int) int { |
| 147 | + j := 0 |
| 148 | + for i := 1; i < len(arr); i++ { |
| 149 | + if arr[i] > arr[j] { |
| 150 | + j = i |
| 151 | + } |
| 152 | + } |
| 153 | + return j |
| 154 | + } |
| 155 | + l, r := 0, len(mat)-1 |
| 156 | + for l < r { |
| 157 | + mid := (l + r) >> 1 |
| 158 | + j := maxPos(mat[mid]) |
| 159 | + if mat[mid][j] > mat[mid+1][j] { |
| 160 | + r = mid |
| 161 | + } else { |
| 162 | + l = mid + 1 |
| 163 | + } |
| 164 | + } |
| 165 | + return []int{l, maxPos(mat[l])} |
| 166 | +} |
| 167 | +``` |
| 168 | + |
| 169 | +### **TypeScript** |
| 170 | + |
| 171 | +```ts |
| 172 | +function findPeakGrid(mat: number[][]): number[] { |
| 173 | + let [l, r] = [0, mat.length - 1]; |
| 174 | + while (l < r) { |
| 175 | + const mid = (l + r) >> 1; |
| 176 | + const j = mat[mid].indexOf(Math.max(...mat[mid])); |
| 177 | + if (mat[mid][j] > mat[mid + 1][j]) { |
| 178 | + r = mid; |
| 179 | + } else { |
| 180 | + l = mid + 1; |
| 181 | + } |
| 182 | + } |
| 183 | + return [l, mat[l].indexOf(Math.max(...mat[l]))]; |
| 184 | +} |
| 185 | +``` |
60 | 186 |
|
| 187 | +### **Rust** |
| 188 | + |
| 189 | +```rust |
| 190 | +impl Solution { |
| 191 | + pub fn find_peak_grid(mat: Vec<Vec<i32>>) -> Vec<i32> { |
| 192 | + let mut l: usize = 0; |
| 193 | + let mut r: usize = mat.len() - 1; |
| 194 | + while l < r { |
| 195 | + let mid: usize = (l + r) >> 1; |
| 196 | + let j: usize = mat[mid] |
| 197 | + .iter() |
| 198 | + .position(|&x| x == *mat[mid].iter().max().unwrap()) |
| 199 | + .unwrap(); |
| 200 | + if mat[mid][j] > mat[mid + 1][j] { |
| 201 | + r = mid; |
| 202 | + } else { |
| 203 | + l = mid + 1; |
| 204 | + } |
| 205 | + } |
| 206 | + let j: usize = mat[l] |
| 207 | + .iter() |
| 208 | + .position(|&x| x == *mat[l].iter().max().unwrap()) |
| 209 | + .unwrap(); |
| 210 | + vec![l as i32, j as i32] |
| 211 | + } |
| 212 | +} |
61 | 213 | ```
|
62 | 214 |
|
63 | 215 | ### **...**
|
|
0 commit comments