一. 题目
-
题目
给你一个数组 arr ,请你将每个元素用它右边最大的元素替换,如果是最后一个元素,用 -1 替换。
完成所有替换操作后,请你返回这个数组。 -
示例
二. 方法一: 暴力法(超时)
-
解题思路
-
解题代码
def replaceElements(self, arr: List[int]) -> List[int]: for i in range(len(arr)): max_size = 0 if i == len(arr) - 1: arr[i] = -1 break for j in range(i + 1, len(arr)): if arr[j] > max_size: max_size = arr[j] arr[i] = max_size return arr
-
分析
时间复杂度: O(n^2)
空间复杂度: O(1)
三. 方法二: 指针法
-
解题思路
- 遍历整个列表
- 然后用两个指针(l, r)来寻找所遍历元素右侧的最大值
- 然后将遍历元素到最大值之间的元素设置为查询到的最大值
- 然后继续遍历后续的元素
- 最终得到正确的结果
-
解题代码
def replaceElements(self, arr: List[int]) -> List[int]: i = 0 # 遍历列表中的元素 while i < len(arr): # 如果是最后一个元素, 则直接赋值为0 if i == len(arr) - 1: arr[i] = -1 break # l: 存储遍历到的最大值的下标 # r: 用于遍历 l = i + 1 j = i + 2 # 遍历寻找最大值 while j < len(arr): # 如果遍历到的结果更大, 则修改最大值的下标 if arr[l] < arr[j]: l = j j += 1 # 将遍历的列表元素到最大值之间的元素全部设置为最大值 for e in range(i, l): arr[e] = arr[l] i = l return arr
-
分析
时间复杂度: O(n^2)??? 不过会比暴力法高效很多
空间复杂度O(1)
四. 方法三: 逆序遍历(官方)
-
解题思路
-
解题代码
def replaceElements(self, arr: List[int]) -> List[int]: size = len(arr) ans = [0] * (size - 1) + [-1] for i in range(size - 2, -1, -1): ans[i] = max(arr[i + 1], ans[i + 1]) return ans
-
分析:
时间复杂度: O(n)
空间复杂度: O(n)彻底懵逼了, 为啥方法二和方法三的运行时间和内存消耗基本一样呢?