Skip to content

Files

Latest commit

2d12a3d · Jun 14, 2024

History

History
167 lines (125 loc) · 5.16 KB

File metadata and controls

167 lines (125 loc) · 5.16 KB
comments difficulty edit_url rating source tags
true
中等
1732
第 109 场双周赛 Q3
数组
动态规划

English Version

题目描述

给你一个下标从 0 开始的整数数组 nums 和一个正整数 x 。

一开始 在数组的位置 0 处,你可以按照下述规则访问数组中的其他位置:

  • 如果你当前在位置 i ,那么你可以移动到满足 i < j 的 任意 位置 j 。
  • 对于你访问的位置 i ,你可以获得分数 nums[i] 。
  • 如果你从位置 i 移动到位置 j 且 nums[i] 和 nums[j] 的 奇偶性 不同,那么你将失去分数 x 。

请你返回你能得到的 最大 得分之和。

注意 ,你一开始的分数为 nums[0] 。

 

示例 1:

输入:nums = [2,3,6,1,9,2], x = 5
输出:13
解释:我们可以按顺序访问数组中的位置:0 -> 2 -> 3 -> 4 。
对应位置的值为 2 ,6 ,1 和 9 。因为 6 和 1 的奇偶性不同,所以下标从 2 -> 3 让你失去 x = 5 分。
总得分为:2 + 6 + 1 + 9 - 5 = 13 。

示例 2:

输入:nums = [2,4,6,8], x = 3
输出:20
解释:数组中的所有元素奇偶性都一样,所以我们可以将每个元素都访问一次,而且不会失去任何分数。
总得分为:2 + 4 + 6 + 8 = 20 。

 

提示:

  • 2 <= nums.length <= 105
  • 1 <= nums[i], x <= 106

解法

方法一:动态规划

根据题目描述,我们可以得到以下结论:

  1. 从位置 i 移动到位置 j 时,如果 n u m s [ i ] n u m s [ j ] 的奇偶性不同,那么会损失 x 分;
  2. 从位置 i 移动到位置 j 时,如果 n u m s [ i ] n u m s [ j ] 的奇偶性相同,那么不会损失分数。

因此,我们可以用一个长度为 2 的数组 f 来表示当前位置的奇偶性为 0 1 时的最大得分。初始时 f 的值为 ,然后我们再初始化

Unable to render expression.

$f[nums[0] &amp; 1] = nums[0]$
,表示初始位置的得分。

接下来,我们从位置 1 开始遍历数组 n u m s ,对于每个位置 i 对应的值 v ,我们更新

Unable to render expression.

$f[v &amp; 1]$
的值为
Unable to render expression.

$f[v &amp; 1]$
Unable to render expression.

$f[v &amp; 1 \oplus 1] - x$
的较大值再加上 v ,即
Unable to render expression.

$f[v &amp; 1] = \max(f[v &amp; 1], f[v &amp; 1 \oplus 1] - x) + v$

答案为 f [ 0 ] f [ 1 ] 中的较大值。

时间复杂度 O ( n ) ,其中 n 为数组 n u m s 的长度。空间复杂度 O ( 1 )

Python3

class Solution:
    def maxScore(self, nums: List[int], x: int) -> int:
        f = [-inf] * 2
        f[nums[0] & 1] = nums[0]
        for v in nums[1:]:
            f[v & 1] = max(f[v & 1], f[v & 1 ^ 1] - x) + v
        return max(f)

Java

class Solution {
    public long maxScore(int[] nums, int x) {
        long[] f = new long[2];
        Arrays.fill(f, -(1L << 60));
        f[nums[0] & 1] = nums[0];
        for (int i = 1; i < nums.length; ++i) {
            int v = nums[i];
            f[v & 1] = Math.max(f[v & 1], f[v & 1 ^ 1] - x) + v;
        }
        return Math.max(f[0], f[1]);
    }
}

C++

class Solution {
public:
    long long maxScore(vector<int>& nums, int x) {
        const long long inf = 1LL << 60;
        vector<long long> f(2, -inf);
        f[nums[0] & 1] = nums[0];
        int n = nums.size();
        for (int i = 1; i < n; ++i) {
            int v = nums[i];
            f[v & 1] = max(f[v & 1], f[v & 1 ^ 1] - x) + v;
        }
        return max(f[0], f[1]);
    }
};

Go

func maxScore(nums []int, x int) int64 {
	const inf int = 1 << 40
	f := [2]int{-inf, -inf}
	f[nums[0]&1] = nums[0]
	for _, v := range nums[1:] {
		f[v&1] = max(f[v&1], f[v&1^1]-x) + v
	}
	return int64(max(f[0], f[1]))
}

TypeScript

function maxScore(nums: number[], x: number): number {
    const f: number[] = Array(2).fill(-Infinity);
    f[nums[0] & 1] = nums[0];
    for (let i = 1; i < nums.length; ++i) {
        const v = nums[i];
        f[v & 1] = Math.max(f[v & 1], f[(v & 1) ^ 1] - x) + v;
    }
    return Math.max(...f);
}