# 2439. Minimize Maximum of Array https://leetcode.com/problems/minimize-maximum-of-array/description/ ###### tags: `Python`,`Leetcode` ## Code ``` python = import math class Solution: def minimizeArrayValue(self, nums: List[int]) -> int: ans = 0 total_sum = 0 for i in range(len(nums)): total_sum += nums[i] ans = max( ans, math.ceil(total_sum /(i + 1))) return ans ``` ## 題意 * 題目會給一個 array ,叫 `nums` * 我們要做的是要讓 array 裡面的 maximum 盡可能減到最低,但這個減的方法比較特別,以 nums[i] 為例: 1. nums[i] value 減一 2. nums[i-1] value 加一 * Example 1 ``` Input: nums = [3,7,1,6] Output: 5 Explanation: One set of optimal operations is as follows: 1. Choose i = 1, and nums becomes [4,6,1,6]. 2. Choose i = 3, and nums becomes [4,6,2,5]. 3. Choose i = 1, and nums becomes [5,5,2,5]. The maximum integer of nums is 5. It can be shown that the maximum number cannot be less than 5. Therefore, we return 5. ``` * Example 2 ``` Input: nums = [10,1] Output: 10 Explanation: It is optimal to leave nums as is, and since 10 is the maximum value, we return 10. ``` ## 思路 * 遍歷 `nums` 中的值,如果現在遇到的數(index = i) 比前一個數大(index = i-1),就可以開始nums[i] value 減一,nums[i-1] value 加一 * 但這個減一加一的狀況,在兩數平均值時會停止 ## 解法 ``` python = import math # 用來叫 ceil()出來作無條件進位 class Solution: def minimizeArrayValue(self, nums: List[int]) -> int: ans = 0 # 紀錄遍歷當下的最大值,最後要 output total_sum = 0 # 用來算平均值用的總和 for i in range(len(nums)): total_sum += nums[i] ans = max( ans, math.ceil(total_sum /(i + 1))) # 如果換到不能再換之後比 ans 大,ans 就要更新 # 算無條件進位:整除時nums[i]、nums[i-1] 會一樣大;不能整除時 nums[i] 要比 nums[i-1] 大 1 return ans ``` ## 補充 * 無條件進位 ceil() 與無條件捨去 floor() 要 import math;如果是四捨五入 round() 字打上去就可以用了 * 如果不使用 ceil(),可以徒手使用 **(total_sum + i)//(i + 1)** * **為何無條件進位可以這樣展開?** 1. 把 total_sum 視為 a , i+1 視為 b 2. 無條件進位 a/b,但會有兩個狀況出現: * a/b 整除,不需進位 **(1)** * a/b 不能整除,需要進位 **(2)** 3. 未達成進位,勢必要再加個什麼,**我假設要加的東西 z:** * a/b + z 要維持整除的數,z < 1 才能不進位 **(1)** * a/b + z要進位, **z > 1 或能讓 a/b 能整除** 才可以進位,但 z > 1 因為上一點已經不可行。 故 z 要讓讓 a/b 能整除 **(2)**: * 補滿小數的缺,補上的數 = 1 -(a/b - a//b) = 1 - 1/b * **1 -(a/b - a//b) 解釋:** 1 - 小數部分 = 補上的缺 * **1 - 1/b 解釋:1 - 小數部分** = 補上的缺(只是我這邊把整數先去掉,留小數處理) 4. 得出 z = 1 - 1/b: * a/b + z = a/b + 1 - 1/b = (a+b-1)/b * 代回 total_sum、i+1,得出 (total_sum + i)//(i + 1)