📌  相关文章
📜  分配给数值上连续且不同的数组元素的子序列的最大分数(1)

📅  最后修改于: 2023-12-03 15:22:38.386000             🧑  作者: Mango

分配给数值上连续且不同的数组元素的子序列的最大分数

问题描述

给定一个整数数组 nums,你需要找到其中最长的且连续的子序列,满足子序列中的元素互不相同(即不重复),并计算该子序列的分数。分数定义为子序列中所有元素的和。

示例

输入:nums = [1,2,3,4,5]

输出:15

解释:最长的连续子序列是 [1,2,3,4,5],分数为 1 + 2 + 3 + 4 + 5 = 15。

输入:nums = [1,2,3,2,5,7,6,4,8]

输出:24

解释:最长的连续子序列是 [2,5,7,6,4],分数为 2 + 5 + 7 + 6 + 4 = 24。注意,[1,2,3] 也是一个子序列,但是它的元素不连续。

解法

本问题可以使用滑动窗口的思想来解决。具体地,从数组的第一个元素开始,往右依次枚举每个元素作为子序列的最后一个元素的情况。在枚举的过程中,可以用一个数组 used 来表示当前已经出现过的元素,同时用 curSum 记录目前选中的子序列的分数之和,maxSum 记录所得分数的最大值。

对于枚举到的每个元素,分为以下两种情况:

  1. 该元素已经出现过,即 used[nums[i]] == true。此时需要从左侧缩小子序列的范围。具体来说,从当前子序列的左边界开始,将 used 中对应的元素的值全部设为 false,并将左边界向右移动,直到 used[nums[i]] == false。
  2. 该元素是第一次出现,即 used[nums[i]] == false。此时可以将该元素加入到当前子序列中,并将 used[nums[i]] 设为 true。

在每次更新了子序列的元素后,需要同时更新 curSum 和 maxSum。其中,curSum 的更新可以直接用 nums[i] 的值加上之前的 curSum,而更新 maxSum 的条件是 curSum 的值比 maxSum 大。

代码实现

以下是使用 Python 语言实现的例子代码:

def maxScore(nums: List[int]) -> int:
    n = len(nums)
    used = [False] * (n + 1)
    left, curSum, maxSum = 0, 0, 0

    for i in range(n):
        while used[nums[i]]:
            used[nums[left]] = False
            curSum -= nums[left]
            left += 1
        used[nums[i]] = True
        curSum += nums[i]
        maxSum = max(maxSum, curSum)

    return maxSum

代码中,我们首先使用列表 used 来记录每个元素是否已经出现过。用 left 表示当前子序列的左边界,curSum 表示当前子序列的分数之和,maxSum 则是目前为止获得的最大分数。随后,我们从数组的第一个元素开始,往右依次枚举每个元素。在每次更新子序列的元素后,需要同时更新 curSum 和 maxSum。最后,将 maxSum 返回即可。

时间复杂度

由于每个元素只被遍历一次,因此算法的时间复杂度为 O(n),其中 n 是数组的长度。

空间复杂度

使用了一个长度为 n+1 的列表 used,因此算法的空间复杂度为 O(n)。