[LeetCode] 1802. Maximum Value at a Given Index in a Bounded Array

You are given three positive integers: nindex, 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 <= n <= maxSum <= 109
  • 0 <= index < n

有界数组中指定下标处的最大值。

给你三个正整数 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 。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/maximum-value-at-a-given-index-in-a-bounded-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

这道题有两种做法,一种是模拟,一种是二分法。这里我暂时提供一个模拟的做法,这里我也提供一个图示。这道题的题目不是很直观,题意是需要我们生成一个整形的数组,如果把数组里面的不同的数字看做山的高度的话,这座山应该是从左往右先往上,到达某个顶点,然后一直往下直到最后。为什么是山形是因为题目的几个条件,相邻元素绝对值的差值 <= 1,元素之和尽量要大,同时峰值在下标 == index 的位置上,但元素之和不能超过 maxSum。

那么我们如何确定这个山形数组的峰顶的高度呢,这里首先我们先模拟的是山脚下的第一层,第一层一定能摆满 - 意思是最后的output数组里面的每个元素都起码是1。此时剩下的数字 = maxSum - n

摆满最底层之后,我们开始摆最顶层,从index的位置开始往左右两边扩散。由于顶层可以只有一个下标有数字,而且这个下标只有可能是题设给的index,那么我们可以先模拟最顶层;模拟完最顶层之后,我们再模拟最顶层下面的一层(也就是从上往下数的第二层),这一层需要以index为中心点往左右两边扩散同时满足这个条件,abs(nums[i] - nums[i+1]) <= 1。按照这个思路,我们从顶层往下一点点看,看看剩余的数字是否能帮我们再多摆一层。

时间O(logM) - M = maxSum - n

空间O(1)

Java实现

 1 class Solution {
 2     public int maxValue(int n, int index, int maxSum) {
 3         // 建立left和right指针,从index位置开始往两侧走
 4         int left = index;
 5         int right = index;
 6         int level = 1;
 7         // 铺完第一层,rest记录剩下的元素个数
 8         int rest = maxSum - n;
 9         while (left > 0 || right < n - 1) {
10             int len = right - left + 1;
11             if (rest >= len) {
12                 rest -= len;
13                 level++;
14                 // 两个指针分别往两侧挪动一个位置
15                 left = Math.max(0, left - 1);
16                 right = Math.min(n - 1, right + 1);
17             } else {
18                 break;
19             }
20         }
21         // 如果maxSum特别大但是n特别小的时候,需要这一步额外操作
22         level += rest / n;
23         return level;
24     }
25 }

 

LeetCode 题目总结

posted @ 2021-04-01 05:22  CNoodle  阅读(405)  评论(0)    收藏  举报