<think>题目要求:求一个二维数组的山顶元素(山顶元素比周围的元素都要大)
注意:周围指的是上、下、左、右、左上、右上、左下、右下8个方向?还是仅上下左右4个方向?
题目没有明确,但通常在山顶元素的问题中,我们考虑8个方向(即所有相邻元素)。但题目示例中只给出了上下左右的情况,但为了严谨,我们按照8个方向来处理。
示例数组:
2 2 2 8 2
2 9 2 2 2
2 2 10 2 2
在这个示例中,山顶元素应该是8、9、10吗?
但是注意:8的右边是2(右边相邻),但8的右上也是2,右下也是2,左边是2,左上左下都是2,上面没有,下面有(9在8的下方?实际上8的位置是(0,3),下面位置(1,3)是2,所以8的周围(8方向)都是2或没有(边界)?所以8是山顶。
9:位置(1,1),上下左右都是2,所以9是山顶。
10:位置(2,2),上下左右都是2,所以10是山顶。
但是注意:8的下面位置(1,3)是2,但是8的下面位置(1,3)的左边位置(1,2)是2,右边位置(1,4)是2,所以8的周围(8个方向)都是2(边界外我们不考虑,所以8的周围只有5个方向:上、下、左、右上、右下?不对,实际上8在边界上,所以只考虑存在的相邻位置。
因此,我们需要考虑边界,只比较存在的相邻位置。
思路:
遍历二维数组的每一个元素,对于每个元素,检查它的8个相邻位置(需要判断边界,避免越界)是否都小于它。如果是,则这个元素就是山顶元素。
步骤:
1. 遍历数组的每个元素a[i][j]。
2. 对于每个元素,检查其8个相邻位置(即(i-1,j-1), (i-1,j), (i-1,j+1), (i,j-1), (i,j+1), (i+1,j-1), (i+1,j), (i+1,j+1))是否存在,如果存在则比较大小。
3. 如果所有存在的相邻元素都小于a[i][j],则a[i][j]是山顶元素。
注意:如果有多个山顶,则全部找出。
示例中,8、9、10都是山顶。
代码实现(使用Python):</think>### 求二维数组的山顶元素
山顶元素是指比其所有相邻元素都大的元素。相邻元素包括上、下、左、右、左上、右上、左下、右下共8个方向(对于边界元素,只考虑存在的相邻位置)。以下是解决此问题的Python实现:
```python
def find_peak_elements(matrix):
if not matrix or not matrix[0]:
return []
rows = len(matrix)
cols = len(matrix[0])
peaks = []
# 定义8个方向的偏移量:上、下、左、右、左上、右上、左下、右下
directions = [(-1, 0), (1, 0), (0, -1), (0, 1),
(-1, -1), (-1, 1), (1, -1), (1, 1)]
for i in range(rows):
for j in range(cols):
current = matrix[i][j]
is_peak = True
# 检查所有相邻方向
for dx, dy in directions:
ni, nj = i + dx, j + dy # 相邻位置坐标
# 检查相邻位置是否在矩阵范围内
if 0 <= ni < rows and 0 <= nj < cols:
# 如果发现相邻元素大于等于当前元素,则不是山顶
if matrix[ni][nj] >= current:
is_peak = False
break
if is_peak:
peaks.append((i, j, current)) # 存储位置和值
return peaks
# 示例矩阵
matrix = [
[2, 2, 2, 8, 2],
[2, 9, 2, 2, 2],
[2, 2, 10, 2, 2]
]
# 查找山顶元素
peaks = find_peak_elements(matrix)
# 输出结果
if peaks:
print("山顶元素位置和值:")
for i, j, val in peaks:
print(f"位置: ({i}, {j}), 值: {val}")
else:
print("没有找到山顶元素")
```
### 代码解释
1. **方向定义**:
```python
directions = [(-1, 0), (1, 0), (0, -1), (0, 1),
(-1, -1), (-1, 1), (1, -1), (1, 1)]
```
定义了8个可能的方向偏移量,用于检查当前元素的邻居。
2. **遍历矩阵**:
```python
for i in range(rows):
for j in range(cols):
```
遍历矩阵中的每个元素。
3. **检查邻居**:
```python
for dx, dy in directions:
ni, nj = i + dx, j + dy
if 0 <= ni < rows and 0 <= nj < cols:
if matrix[ni][nj] >= current:
is_peak = False
break
```
对于每个元素,检查其8个方向的邻居:
- 首先计算邻居坐标 `(ni, nj)`
- 验证坐标是否在矩阵范围内
- 如果存在邻居值大于等于当前元素,标记为非山顶
4. **结果收集**:
```python
if is_peak:
peaks.append((i, j, current))
```
如果所有邻居都小于当前元素,将其记录为山顶元素。
### 示例输出
对于给定的矩阵:
```
[2, 2, 2, 8, 2]
[2, 9, 2, 2, 2]
[2, 2, 10, 2, 2]
```
程序将输出:
```
山顶元素位置和值:
位置: (0, 3), 值: 8
位置: (1, 1), 值: 9
位置: (2, 2), 值: 10
```
### 算法特点
- **时间复杂度**:O(rows × cols × 8),简化为 O(n²),其中 n 是矩阵维度
- **空间复杂度**:O(1)(不考虑输出存储空间)
- **边界处理**:自动处理矩阵边界,只检查存在的邻居
- **多个山顶**:能够找出矩阵中所有符合条件的山顶元素