leetcode
leetcode 2451 ~ 2500
平衡子序列的最大和

平衡子序列的最大和

难度:

标签:

题目描述

You are given a 0-indexed integer array nums.

A subsequence of nums having length k and consisting of indices i0 < i1 < ... < ik-1 is balanced if the following holds:

  • nums[ij] - nums[ij-1] >= ij - ij-1, for every j in the range [1, k - 1].

A subsequence of nums having length 1 is considered balanced.

Return an integer denoting the maximum possible sum of elements in a balanced subsequence of nums.

A subsequence of an array is a new non-empty array that is formed from the original array by deleting some (possibly none) of the elements without disturbing the relative positions of the remaining elements.

 

Example 1:

Input: nums = [3,3,5,6]
Output: 14
Explanation: In this example, the subsequence [3,5,6] consisting of indices 0, 2, and 3 can be selected.
nums[2] - nums[0] >= 2 - 0.
nums[3] - nums[2] >= 3 - 2.
Hence, it is a balanced subsequence, and its sum is the maximum among the balanced subsequences of nums.
The subsequence consisting of indices 1, 2, and 3 is also valid.
It can be shown that it is not possible to get a balanced subsequence with a sum greater than 14.

Example 2:

Input: nums = [5,-1,-3,8]
Output: 13
Explanation: In this example, the subsequence [5,8] consisting of indices 0 and 3 can be selected.
nums[3] - nums[0] >= 3 - 0.
Hence, it is a balanced subsequence, and its sum is the maximum among the balanced subsequences of nums.
It can be shown that it is not possible to get a balanced subsequence with a sum greater than 13.

Example 3:

Input: nums = [-2,-1]
Output: -1
Explanation: In this example, the subsequence [-1] can be selected.
It is a balanced subsequence, and its sum is the maximum among the balanced subsequences of nums.

 

Constraints:

  • 1 <= nums.length <= 105
  • -109 <= nums[i] <= 109

代码结果

运行时间: 555 ms, 内存: 40.9 MB


解释

方法:

该题解采用了动态规划的思路。首先,每个元素的值与其下标之差(num - idx)被使用来确定该元素能否成为平衡子序列的一部分。我们维护一个pool数组,它保存所有考虑过的num-idx的值,并保持递增顺序。同时,我们使用一个字典emax来存储每个不同的num-idx值所能达到的最大子序列和。遍历数组nums时,我们检查当前num-idx能插入pool的位置,并更新当前元素的最大可能序列和,同时更新emax。最后,我们在整个遍历过程中追踪可能的最大和。

时间复杂度:

O(n log n)

空间复杂度:

O(n)

代码细节讲解

🦆
为什么在确定平衡子序列时,要使用每个元素的值减去其下标(num - idx)这一操作?这样操作的目的和效果是什么?
在这个问题中,使用每个元素的值减去其下标(num - idx)的操作是用来确定哪些元素可以形成一个平衡子序列。如果两个元素的num-idx值相同,那么这两个元素之间的序列可能是平衡的。这是因为如果num1-idx1等于num2-idx2,那么num1-num2等于idx1-idx2,即元素的增量相等于下标的增量,这是平衡序列的一个特征。通过这种方式,可以更容易地通过动态规划构建出最大的平衡子序列和。
🦆
在动态规划中,你是如何定义状态转移方程的?具体来说,`cur = max(emax[pool[i-1]] + num, cur)`这一步的逻辑基础是什么?
状态转移方程的定义基于最优子结构的概念。在这里,`cur`代表以当前元素num结尾的最大平衡子序列和。`emax[pool[i-1]]`代表在当前元素之前,且具有小于或等于当前num-idx值的最大子序列和。如果存在这样的子序列,那么当前元素可以加入该子序列来可能形成一个更大的和。因此,状态转移方程`cur = max(emax[pool[i-1]] + num, cur)`表示考虑将当前元素加入前一个有效子序列或单独作为一个子序列的两种情况,取两者的最大值。
🦆
你提到使用二分查找插入元素以保持pool数组的有序性,但在更新pool时,使用了线性搜索来维持emax的递增顺序。这种方法的效率如何,有没有更高效的更新方式?
虽然二分查找可以高效地找到插入位置以保持pool的有序性,但在更新pool和emax时使用线性搜索可能降低效率,特别是在数组长度较大时。线性搜索导致的时间复杂度可能达到O(n^2)。一种更高效的方法可能是使用数据结构如平衡二叉搜索树(如红黑树)或跳表来同时维持pool的有序性和高效地更新emax,这样每次插入和更新的操作平均时间复杂度都可以保持在O(log n)。
🦆
在字典emax中,你是如何决定何时更新现有的num-idx键值对,以及何时添加新的键值对的?这一策略的优势和潜在的风险是什么?
在字典emax中,如果num-idx键已存在,则检查当前计算的子序列和是否大于已存储的值,如果大于,则进行更新。如果键不存在,则添加新的键值对。这种策略的优势在于可以确保每个num-idx值都对应其可能的最大子序列和,从而在遍历时能够获取到最优解。然而,这种策略的风险在于可能会存储大量的num-idx值,特别是对于大数组,这可能导致空间复杂度上升,同时更新操作可能会导致一定的时间开销。

相关问题