LeetCode_贪心_二分搜索_中等_1802.有界数组中指定下标处的最大值
2023-09-27 14:25:45 时间
1.题目
给你三个正整数 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
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/maximum-value-at-a-given-index-in-a-bounded-array
2.思路
(1)暴力穷举法
① 用 res 来表示 nums[index],并从 res = maxSum 开始,穷举 res,以保证 nums[index] 的值被最大化;
② 在穷举的过程中,用 sum 表示数组 nums 的所有元素之和,如果 sum <= maxSum,则说明找到了满足题目所有条件的数组 nums,此时直接返回 res 即可;否则 res–,继续下一轮穷举;
③ 当 res < 1 时,结束穷举;
需要注意的是,该方法的时间复杂度较高,为 O(mn),所以在 LeetCode 中提交会出现“超出时间限制”的情况!
(2)贪心算法 & 二分搜索
思路参考本题官方题解。
3.代码实现(Java)
//思路1————暴力穷举法
class Solution {
public int maxValue(int n, int index, int maxSum) {
// 用 res 来表示 nums[index]
int res = maxSum;
//从 res = maxSum 开始,枚举 res,以保证 nums[index] 的值被最大化
while (res >= 1) {
// sum 表示数组 nums 的所有元素之和
long sum = res;
//计算 nums[index + 1...0] 的和
for (int i = index + 1; i < n; i++) {
sum += Math.max(res - i + index, 1);
}
//计算 nums[0...index - 1] 的和
for (int i = index - 1; i >= 0; i--) {
sum += Math.max(res - index + i, 1);
}
//保证数组 nums 的元素之和不超过 maxSum
if (sum <= maxSum) {
return res;
}
res--;
}
return -1;
}
}
//思路2————贪心算法 & 二分搜索
class Solution {
public int maxValue(int n, int index, int maxSum) {
int leftCnt = index;
int rightCnt = n - index - 1;
//二分查找的左右边界(1 <= nums[index] <= maxSum)
int left = 1;
int right = maxSum;
while (left <= right) {
int mid = left + (right - left) / 2;
long sum = mid + calPartSum(mid, leftCnt) + calPartSum(mid, rightCnt);
if (sum > maxSum) {
right = mid - 1;
} else {
left = mid + 1;
}
}
return left - 1;
}
private long calPartSum(int maxNum, int cnt) {
if (maxNum > cnt) {
/*
[maxNum - 1, maxNum - 2, ..., maxNum - cnt],一共有 cnt 个数
可直接使用等差数列的求和公式:(首项 + 尾项) * 项数 / 2
*/
return (long) (maxNum - 1 + maxNum - cnt) * cnt / 2;
} else {
/*
maxNum <= cnt
[maxNum - 1, maxNum - 2, ..., maxNum - cnt = 1, 1, ..., 1],一共有 cnt 个数
分两部分求和:[maxNum - 1, maxNum - 2, ..., 1] + [1, 1, ..., 1],分别有 maxNum - 1 和 cnt - (maxNum - 1) 个数
*/
return (long) (maxNum - 1 + 1) * (maxNum - 1) / 2 + cnt - (maxNum - 1);
}
}
}
相关文章
- LeetCode:搜索二维矩阵题解
- 【LeetCode】解码方法 II [H](记忆化搜索)
- 【LeetCode】矩阵置零 [M](矩阵)
- 【LeetCode】单词搜索 II [H](前缀树)
- 【LeetCode】移除盒子 [H](记忆化搜索)
- [leetcode]Combinations
- [leetcode]Best Time to Buy and Sell Stock III
- [leetcode]Gray Code
- LeetCode_二分搜索_困难_154.寻找旋转排序数组中的最小值 II
- LeetCode_贪心算法_中等_738.单调递增的数字
- LeetCode_二分搜索_容斥原理_困难_878.第 N 个神奇数字
- LeetCode_二分搜索_简单_69. x 的平方根
- LeetCode_动态规划_中等_714.买卖股票的最佳时机含手续费
- LeetCode_动态规划_二分搜索_困难_354.俄罗斯套娃信封问题
- LeetCode_贪心算法_中等_55.跳跃游戏
- LeetCode_二分搜索_困难_4.寻找两个正序数组的中位数
- LeetCode·每日一题·481.神奇字符串·模拟构造
- LeetCode·701.二叉搜索树中的插入操作·递归
- leetcode面试题16.24-在无序数组中所有发现和为sum的数对
- [LeetCode] 173. Binary Search Tree Iterator 二叉搜索树迭代器
- leetcode 96不同的二叉搜索树