1846. 减小和重新排列数组后的最大元素
对数组进行排序,那么数组中相邻两个元素,要么后者等于前者,要么后者等于前者加上 1。
状态:dp[j] 是 arr 中前 j 个可能的 最大值 。
边界:dp[0] = 1
转移方程:dp[j] = min(dp[j-1]+1, arr[j])
if arr[j] > dp[j-1]: # 后面的数比前面的大
dp[j] = dp[j-1] + 1
else: # 前后相等 dp[j-1] == arr[j]
dp[j] = arr[j]
返回:dp[-1]
方法一:动态规划
class Solution:
def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:
n = len(arr)
if n == 1:return 1
arr.sort()
dp = [1]*n
# dp[0] = 1
for j in range(1, n):
dp[j] = min(dp[j-1]+1, arr[j])
return dp[-1]
因为 dp[j] 只和 dp[j-1] 有关系,所以用一个变量 pre 代替 dp。
class Solution:
def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:
n = len(arr)
if n == 1: return 1
arr.sort()
pre = 1
print(n)
for i in range(1, n):
if abs(arr[i]-pre) >= 1:
pre += 1
else:
pre = arr[i]
return pre
简化
class Solution:
def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:
arr.sort()
pre = 1
for num in arr[1:]:
pre = min(pre+1, num)
return pre
用 arr 代替 dp
class Solution:
def maximumElementAfterDecrementingAndRearranging(self, arr: List[int]) -> int:
n = len(arr)
if n == 1: return 1
arr.sort()
arr[0] = 1
for i in range(1,n):
arr[i] = min(arr[i], arr[i-1] + 1)
return arr[-1]