comments | difficulty | edit_url | rating | source | tags | ||
---|---|---|---|---|---|---|---|
true |
中等 |
1929 |
第 233 场周赛 Q3 |
|
给你三个正整数 n
、index
和 maxSum
。你需要构造一个同时满足下述所有条件的数组 nums
(下标 从 0 开始 计数):
nums.length == n
nums[i]
是 正整数 ,其中0 <= i < n
abs(nums[i] - nums[i+1]) <= 1
,其中0 <= i < n-1
nums
中所有元素之和不超过maxSum
nums[index]
的值被 最大化
返回你所构造的数组中的 nums[index]
。
注意:abs(x)
等于 x
的前提是 x >= 0
;否则,abs(x)
等于 -x
。
示例 1:
输入:n = 4, index = 2, maxSum = 6 输出:2 解释:数组 [1,1,2,1] 和 [1,2,2,1] 满足所有条件。不存在其他在指定下标处具有更大值的有效数组。
示例 2:
输入:n = 6, index = 1, maxSum = 10 输出:3
提示:
1 <= n <= maxSum <= 109
0 <= index < n
根据题目描述,如果我们确定了
这样我们就可以计算出数组的总和,如果总和小于等于
为了方便计算数组左侧、右侧的元素之和,我们定义一个函数
- 如果
$x \geq cnt$ ,那么数组的总和为$\frac{(x + x - cnt + 1) \times cnt}{2}$ - 如果
$x \lt cnt$ ,那么数组的总和为$\frac{(x + 1) \times x}{2} + cnt - x$
接下来,定义二分的左边界
最后将
时间复杂度
class Solution:
def maxValue(self, n: int, index: int, maxSum: int) -> int:
def sum(x, cnt):
return (
(x + x - cnt + 1) * cnt // 2 if x >= cnt else (x + 1) * x // 2 + cnt - x
)
left, right = 1, maxSum
while left < right:
mid = (left + right + 1) >> 1
if sum(mid - 1, index) + sum(mid, n - index) <= maxSum:
left = mid
else:
right = mid - 1
return left
class Solution {
public int maxValue(int n, int index, int maxSum) {
int left = 1, right = maxSum;
while (left < right) {
int mid = (left + right + 1) >>> 1;
if (sum(mid - 1, index) + sum(mid, n - index) <= maxSum) {
left = mid;
} else {
right = mid - 1;
}
}
return left;
}
private long sum(long x, int cnt) {
return x >= cnt ? (x + x - cnt + 1) * cnt / 2 : (x + 1) * x / 2 + cnt - x;
}
}
class Solution {
public:
int maxValue(int n, int index, int maxSum) {
auto sum = [](long x, int cnt) {
return x >= cnt ? (x + x - cnt + 1) * cnt / 2 : (x + 1) * x / 2 + cnt - x;
};
int left = 1, right = maxSum;
while (left < right) {
int mid = (left + right + 1) >> 1;
if (sum(mid - 1, index) + sum(mid, n - index) <= maxSum) {
left = mid;
} else {
right = mid - 1;
}
}
return left;
}
};
func maxValue(n int, index int, maxSum int) int {
sum := func(x, cnt int) int {
if x >= cnt {
return (x + x - cnt + 1) * cnt / 2
}
return (x+1)*x/2 + cnt - x
}
return sort.Search(maxSum, func(x int) bool {
x++
return sum(x-1, index)+sum(x, n-index) > maxSum
})
}