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]