You are given three positive integers: n, index, and maxSum. You want to construct an array nums (0-indexed) that satisfies the following conditions:
nums.length == n
nums[i] is a positive integer where 0 <= i < n.
abs(nums[i] - nums[i+1]) <= 1 where 0 <= i < n-1.
The sum of all the elements of nums does not exceed maxSum.
nums[index] is maximized.
Return nums[index] of the constructed array.
Note that abs(x) equals x if x >= 0, and -x otherwise.
Example 1:
Input: n = 4, index = 2, maxSum = 6
Output: 2
Explanation: nums = [1,2,2,1] is one array that satisfies all the conditions.
There are no arrays that satisfy all the conditions and have nums[2] == 3, so 2 is the maximum nums[2].
Example 2:
Input: n = 6, index = 1, maxSum = 10
Output: 3
Constraints:
1 2
1 <= n <= maxSum <= 109 0 <= index < n
解题思路
首先将题意转化成自己的理解
给我三个参数n, index, maxSum
nums.length = n
nums[i]中的元素为正整数(不要看错了)
nums中相邻的两个元素的绝对值<=1
sum(nums)不超过numSum
nums[index]尽可能地大
想让nums[index]最大化有以下思路:
在sum(nums) <= numSum下尽可能增大nums[index]
让sum(nums)增长的尽可能缓慢
sum(nums)求和公式为:
s = index左 + nums[index] + index右 + 未被占用的元素下标(为了尽可能的小所以默认都是1)
classSolution: defmaxValue(self, n: int, index: int, maxSum: int) -> int: defcheck(num) -> bool: # 初始化 leftLength, leftMin = min(index - 0, num - 1), num - min(index - 0, num - 1) # 左长度 左最小元素 indexLeft = leftLength * leftMin + leftLength * (leftLength - 1) / 2# 求出左边的和 rightLength, rightMin = min(n - index - 1, num - 1), num - min(n - index - 1, num - 1) # 右长度 右最小元素 indexRight = rightLength * rightMin + rightLength * (rightLength - 1) / 2# 求出右边的和 element = 0if (numsLeft - leftLength) + (numsRight - rightLength) < 0else (numsLeft - leftLength) + (numsRight - rightLength) s = indexLeft + num + indexRight + element # sum(nums) return s > maxSum
# 初始化 l, r = 1, 10 ** 9 + 1# 二分上下界 numsLeft, numsRight = index - 0, n - index - 1# nums除去index后的左右长度 ans = 0 while l <= r: mid = (r - l >> 1) + l if check(mid): r = mid - 1 else: l = mid + 1 ans = max(ans, mid) return ans
classSolution { public: intmaxValue(int n, int index, int maxSum){ int left = 1, right = maxSum; while (left < right) { int mid = (left + right + 1) / 2; if (valid(mid, n, index, maxSum)) { left = mid; } else { right = mid - 1; } } return left; }
boolvalid(int mid, int n, int index, int maxSum){ int left = index; int right = n - index - 1; return mid + cal(mid, left) + cal(mid, right) <= maxSum; }
longcal(int big, int length){ if (length + 1 < big) { int small = big - length; return (long) (big - 1 + small) * length / 2; } else { int ones = length - (big - 1); return (long) big * (big - 1) / 2 + ones; } } };