你的位置:IM体育官方网站首页 > IM资讯 >


IM体育官网 2026-03-30: 轮回分裂的最大得分。用go谈话, 给你一个轮回数组 nu

发布日期:2026-03-30 17:38    点击次数:198


IM体育官网 2026-03-30: 轮回分裂的最大得分。用go谈话, 给你一个轮回数组 nu

你需要把这个轮回数组切成最多 k 段流畅子数组。因为数组是轮回的,这些子数组的切分允许从数组末尾不时“绕回”到起首,是以子数组仍然条款是流畅的元素序列(但不错超过末尾到起首的领域)。

对恣意一段子数组,先找出它内部的最大值和最小值,然后缱绻这段子数组的“领域”,界说为:

最大值 − 最小值

一次分裂的总得分等于整个子数组的领域之和。

在整个可能的轮回分裂形式中,你要复返梗概取得的最大总得分。

1

1

1

输入: nums = [1,2,3,3], k = 2。

输出: 3。

讲授:

将 nums 分裂为 [2, 3] 和 [3, 1](环绕)。

[2, 3] 的领域是 max(2, 3) - min(2, 3) = 3 - 2 = 1。

[3, 1] 的领域是 max(3, 1) - min(3, 1) = 3 - 1 = 2。

总得分为 1 + 2 = 3。

题目来独力扣3743。

一、先明确题目中枢规矩

1. 轮回数组:数组首尾贯串,切分的子数组不错跨数组末尾+起首(比如数组[1,2,3,3],子数组[3,1]是正当的)。

2. 切分条款:把轮回数组切成最多k段流畅子数组(不错切1~k段,不是必须切k段)。

3. 得分缱绻:每段子数组的得分 = 子数组最大值 - 子数组最小值;总得分 = 整个子段得分之和。

4. 指标:找到整个切分形式中最大的总得分。

二、解题中枢冲破口(关节滚动)

这谈题最中枢的数学滚动:

总得分 = 整个子段的(max-min)之和 = 通盘数组的全局最大值出现的总次数 - 全局最小值出现的总次数

简化论断:

要让总得分最大,只需要让全局最大值尽可能多的单独成段/拆分出来,全局最小值尽可能多的单独成段/拆分出来。

基于这个论断,解题第一步:

1. 找到数组中的全局最大值(记为maxVal),并纪录它的恣意一个位置maxI。

2. 轮回数组的最优切分,一定是以全局最大值为起初/绝顶张开的(因为最大值是得分的中枢来源)。

三、举座解题身手(分4大阶段)

阶段1:找到全局最大值的位置

遍历通盘数组,找到数值最大的元素,纪录它的下标maxI。

示例nums=[1,2,3,3]:全局最大值是3,位置是下标2或3。

阶段2:处分轮回数组(破环成链)

轮回数组无法平直缱绻,咱们用破环法:

把原数组复制一份拼接在后头,酿成长度为2n的线性数组,这么整个轮回流畅子数组,都能在这个长数组中找到对应的流畅片断。

阶段3:两种中枢切分场景(散失整个轮回最优解)

因为是轮回数组,全局最大值maxI的位置决定了两种最优切分可能:

1. 场景1:全局最大值当作第一段的第一个元素,向后切分最多k段;

2. 场景2:全局最大值当作临了一段的临了一个元素,向后切分最多k段。

代码均分别缱绻这两种场景的最大得分:

• ans1:场景1的最大得分

• ans2:场景2的最大得分

最终谜底等于ans1和ans2中的较大值。

阶段4:动态决策缱绻单场景最大得分(中枢缱绻过程)

针对每一种切分场景,用动态决策缱绻「最多切k段」的最大总得分,身手如下:

1. 驱动化DP景象

界说景象暗示:

• 用三维景象纪录「切了j段」「现时是否合手有/是否完成走动」(对应拆分最大值、最小值的收益);

• 驱动景象:未切分的技巧收益为负无限(不测旨),IM体育只消驱动空景象正当。

2. 遍历数组元素,逐位更新DP

从指定起初入手,遍历n个元素(对应原数组长度),对每个元素:

• 倒序遍历切分段数(从k+1段到1段,幸免重迭缱绻);

• 三种景象转机:

不操作:保合手现时收益不变;

卖出:规定现时子段,结算收益(对应子段的max-min);

买入:入手新的子段,纪录资本。

3. 最终取值

遍历规定后,DP数组中存储的等于「最多切k段」能取得的最大总得分。

四、齐备历程总览(连合示例)

以nums=[1,2,3,3],k=2为例:

1. 找到全局最大值3,位置是下标2;

2. 破环成链得到[1,2,3,3,1,2,3,3];

3. 缱绻两种场景:

• 场景1:从下标2入手切分,最多2段;

• 场景2:从下标3入手切分,最多2段;

4. 动态决策缱绻出两种场景的得分分别为2和3;

5. 取最大值3,等于最终谜底。

五、技巧复杂度 & 极度空间复杂度

1. 总技巧复杂度

• 找全局最大值:遍历数组1次,复杂度O(n);

• 两次动态决策缱绻:每次遍历n个元素,每层遍历k个段数,复杂度O(n*k);

• 总技巧复杂度:O(n*k)。

补充:n是数组长度,k是最大切分段数,n≤1000,都备怡悦题目条款。

2. 总和外空间复杂度

• 动态决策使用了二维数组(k+2) × 3,空间O(k);

• 无其他大型赞助数组;

• 总和外空间复杂度:O(k)。

追念

1. 中枢想路:应用全局最大/最小值滚动得分,破环成链处分轮回数组;

2. 缱绻形式:两种起初场景+动态决策求最大得分;

3. 技巧复杂度:O(n*k),空间复杂度:O(k)。

Go齐备代码如下:

package main

import (

"fmt"

"math"

)

// 3573. 交易股票的最好时机 V

func maximumProfit(prices []int, l, r, k int)int64 {

n := len(prices)

f := make([][3]int, k+2)

for j := 1; j

f[j][1] = math.MinInt / 2

f[j][2] = math.MinInt / 2

}

f[0][0] = math.MinInt / 2

for i := l; i

p := prices[i%n]

for j := k + 1; j > 0; j-- {

f[j][0] = max(f[j][0], f[j][1]+p, f[j][2]-p)

f[j][1] = max(f[j][1], f[j-1][0]-p)

f[j][2] = max(f[j][2], f[j-1][0]+p)

}

}

returnint64(f[k+1][0])

}

func maximumScore(nums []int, k int)int64 {

n := len(nums)

maxI := 0

for i, x := range nums {

if x > nums[maxI] {

maxI = i

}

}

ans1 := maximumProfit(nums, maxI, maxI+n, k) // nums[maxI] 是第一个数

ans2 := maximumProfit(nums, maxI+1, maxI+1+n, k) // nums[maxI] 是临了一个数

return max(ans1, ans2)

}

func main {

nums := []int{1, 2, 3, 3}

k := 2

result := maximumScore(nums, k)

fmt.Println(result)

}

Python齐备代码如下:

# -*-coding:utf-8-*-

from typing import List

def maximumProfit(prices: List[int], l: int, r: int, k: int) -> int:

n = len(prices)

# 创建dp数组: f[j][0], f[j][1], f[j][2]

f = [[0, 0, 0] for _ in range(k + 2)]

# 驱动化

for j in range(1, k + 2):

f[j][1] = -10**9 # 相配于 math.MinInt/2

f[j][2] = -10**9

f[0][0] = -10**9

for i in range(l, r):

p = prices[i % n]

# 倒序遍历j

for j in range(k + 1, 0, -1):

f[j][0] = max(f[j][0], f[j][1] + p, f[j][2] - p)

f[j][1] = max(f[j][1], f[j-1][0] - p)

f[j][2] = max(f[j][2], f[j-1][0] + p)

return f[k+1][0]

def maximumScore(nums: List[int], k: int) -> int:

n = len(nums)

maxI = 0

for i, x in enumerate(nums):

if x > nums[maxI]:

maxI = i

# nums[maxI] 是第一个数

ans1 = maximumProfit(nums, maxI, maxI + n, k)

# nums[maxI] 是临了一个数

ans2 = maximumProfit(nums, maxI + 1, maxI + 1 + n, k)

return max(ans1, ans2)

def main:

nums = [1, 2, 3, 3]

k = 2

result = maximumScore(nums, k)

print(result)

if __name__ == "__main__":

main

C++齐备代码如下:

#include

#include

#include

#include

using namespace std;

// 3573. 交易股票的最好时机 V

long long maximumProfit(vector& prices, int l, int r, int k) {

int n = prices.size;

// 创建dp数组: f[j][0], f[j][1], f[j][2]

vector> f(k + 2, vector(3));

// 驱动化

for (int j = 1; j

f[j][1] = INT_MIN / 2;

f[j][2] = INT_MIN / 2;

}

f[0][0] = INT_MIN / 2;

for (int i = l; i

int p = prices[i % n];

for (int j = k + 1; j > 0; j--) {

f[j][0] = max({f[j][0], f[j][1] + p, f[j][2] - p});

f[j][1] = max(f[j][1], f[j-1][0] - p);

f[j][2] = max(f[j][2], f[j-1][0] + p);

}

}

return (long long)f[k+1][0];

}

long long maximumScore(vector& nums, int k) {

int n = nums.size;

int maxI = 0;

for (int i = 0; i

if (nums[i] > nums[maxI]) {

maxI = i;

}

}

long long ans1 = maximumProfit(nums, maxI, maxI + n, k); // nums[maxI] 是第一个数

long long ans2 = maximumProfit(nums, maxI + 1, maxI + 1 + n, k); // nums[maxI] 是临了一个数

return max(ans1, ans2);

}

int main {

vector nums = {1, 2, 3, 3};

int k = 2;

long long result = maximumScore(nums, k);

cout

return0;

}

咱们肯定东谈主工智能为庸碌东谈主提供了一种“增强器具”,并勤劳于共享全主义的AI学问。在这里,您不错找到最新的AI科普著述、器具评测、晋升成果的隐秘以及行业洞悉。

宽宥慈祥“福大大架构师逐日一题”IM体育官网,发音讯可取得口试费力,让AI助力您的将来发展。

开云app官方在线入口

    热点资讯

    推荐资讯