鑫诚防腐保温工程有限公司

阿坝储罐保温施工 2026-08-11: 距离至少为 K 的瓜代子序列的大和。用go说话, 给定

发布日期:2026-08-12 12:23:22|点击次数:181
铁皮保温

2026-08-11:距离至少为 K 的瓜代子序列的大和。用go说话阿坝储罐保温施工,给定个整数数组和个整数 k,你需要从中挑选个下标严格递加的子序列。挑选时须欢快相邻两个下标之差至少为 k。同期,这些下标对应的数值须组成个严格瓜代的序列:即要么按照“小、大、小、大……”的花式波动,要么按照“大、小、大、小……”的花式波动,相邻元素之间的大小关联瓜代变化且不成相等。只包含个元素的子序列也视为法瓜代。该子序列的得分界说为其中总计元素之和。请你狡计在总计欢快条款的子序列中,大略赢得的大得分。

1

1

1

输入: nums = [5,4,2], k = 2。

输出: 7。

评释注解:

种选拔是下标 [0, 2],对应的值为 [5, 2]。

距离条款设置,因为 2 - 0 = 2 >= k。

这些值严格瓜代,因为 5 > 2。

得分为 5 + 2 = 7。

题目来独力扣3915。

大体标准如下:

1. 值域破裂化

原数组中的数值限制可能较大(大到 100000,但相对个数多 100000),径直按值汲引树状数组会奢侈空间。因此先将所特地值排序、去重,得到个紧凑的有序数组 sorted。之后每个原始数值皆不错用它在 sorted 中的下标(即排行)来暗示,排行从 0 到 m-1(m 为不同值的个数)。这么就将值域压缩到了 [0, m-1] 的整数限制,便于树状数组贬责。

2. 界说气象

关于每个下标 i,界说两种气象:

• fInc[i]:以 nums[i] 扫尾、且子序列后两项呈现递加关联(即前个数

• fDec[i]:以 nums[i] 扫尾、且子序列后两项呈现递减关联(即前个数 > nums[i])的瓜代子序列的大和。

长度为 1 的子序列既不错视为“递加扫尾”,也不错视为“递减扫尾”,其和便是 nums[i] 自身。这两种气象袒护了总计可能的瓜代花式(小大小大... 或 大小大小...)。

3. 运行化两个树状数组(Fenwick Tree)

树状数组用于维持值域区间内的大 DP 值,撑抓单点取 max 新和前缀大值查询,每次操作均为 O(log m)。

• inc 树状数组:用于维持以递加扫尾的气象 fInc。为了大略便地查询“值大于现时值”的总计气象,它在里靠近索引进行了回转映射。

• dec 树状数组:用于维持以递减扫尾的气象 fDec,遴选原值域轨则,查询“值小于现时值”的气象。

两个树状数组大小均为 m+1,使用 1‑based 索引。

4. 遍历数组,动态联想出动

按轨则遍历数组 i = 0 到 n-1,对每个元素 x = nums[i] 奉行以下子标准:

4.1 距离敛迹的“蔓延加入”

题目要求选中子序列的相邻下标之差 ≥ k。为了欢快这条款,咱们遴选蔓延激活的政策:

独一当 i ≥ k 时,才将下标 i-k 对应的气象加入到树状数组中,使其不错被现时及之后的下标使用。这保证了出动着手的原始下标与现时下地方距离至少为 k。

加入的具体操看成:

• 取出 i-k 位置已破裂化的值 j_prev(该值在之前遍历时已被替换为排行)。

• 新 inc:在位置 m - j_prev 上新为 max(原值, fInc[i-k])。

这步诓骗了回转索引,把底本的“后缀查询”转机为树状数组擅长的“前缀查询”。

• 新 dec:在位置 j_prev + 1 上新为 max(原值, fDec[i-k])。

4.2 现时元素的破裂化

在现时元素 x 上使用二分查找,得到其在 sorted 中的排行 j(0‑based)。为了后续标准 i+k 大略径直使用该排行而需再次二分,将 nums[i] 速即修改为 j(因为原值之后不再需要)。

4.3 狡计现时气象

• 狡计 fInc[i]:需要找个先行者气象,它须是递减扫尾(fDec),设备保温施工且其对应的值严格小于 x(即排行

在 dec 树状数组中查询前缀 [1, j](对应排行 ≤ j-1)的大值,加上 x 即可得到 fInc[i]。若不存在这么的先行者,查询复返 0,则 fInc[i] = x,对应单位素子序列。

• 狡计 fDec[i]:需要找个先行者气象,它是递加扫尾(fInc),且其值严格大于 x(即排行 > j)。

通过回转索引,在 inc 树状数组中查询前缀 [1, m-1-j](对应排行 ≥ j+1)的大值,加上 x 得到 fDec[i]。

4.4 新全局谜底

用刚刚算出的 fInc[i] 和 fDec[i] 去新全局大得分 ans。

5. 输出效果

遍历完通盘数组后,ans 即为总计欢快条款的子序列的大得分。

复杂度分析

• 工夫复杂度:

破裂化排序 O(n log n);主轮回奉行 n 次,每次包含次二分查找 O(log m) 和两次树状数组操作(新/查询)均为 O(log m)。由于 m ≤ n,总工夫复杂度为 O(n log n)。

• 特地空间复杂度:

破裂化数组 sorted 占用 O(m);DP 数组 fInc 和 fDec 各占用 O(n);两个树状数组各占用 O(m)。举座特地空间为 O(n)。

Go齐备代码如下:

.

package main

import (

"fmt"

"slices"

"sort"

)

type fenwick []int64

func (f fenwick) update(i int, val int64) {

for ; i

f[i] = max(f[i], val)

}

}

// [1, i] 中的大值

func (f fenwick) preMax(i int) (res int64) {

for ; i > 0; i &= i - 1 {

res = max(res, f[i])

}

return

}

func maxAlternatingSum(nums []int, k int) (ans int64) {

// 破裂化 nums

sorted := slices.Clone(nums)

slices.Sort(sorted)

sorted = slices.Compact(sorted)

n := len(nums)

fInc := make([]int64, n) // fInc[i] 暗示以 nums[i] 扫尾且后两项递加的瓜代子序列的大和

fDec := make([]int64阿坝储罐保温施工, n) // fDec[i] 暗示以 nums[i] 扫尾且后两项递减的瓜代子序列的大和

// 值域树状数组

m := len(sorted)

inc := make(fenwick, m+1) // 维持 fInc[i] 的大值

dec := make(fenwick, m+1) // 维持 fDec[i] 的大值

for i, x := range nums {

if i >= k {

// 在这个时候才把 fInc[i-k] 和 fDec[i-k] 添加到值域树状数组中,从而保证出动着手的下标

j := nums[i-k]

inc.update(m-j, fInc[i-k]) // m-j 不错把后缀酿成前缀

dec.update(j+1, fDec[i-k])

}

j := sort.SearchInts(sorted, x)

nums[i] = j // 防护这里修改了 nums[i],这么上头的 nums[i-k] 需二分

fInc[i] = dec.preMax(j) + int64(x) // 狡计欢快 nums[i']

fDec[i] = inc.preMax(m-1-j) + int64(x) // 狡计欢快 nums[i'] > x 的 fInc[i'] 的大值

ans = max(ans, fInc[i], fDec[i]) // 陈列子序列以 nums[i] 扫尾

}

return

}

func main {

nums := []int{5, 4, 2}

k := 2

result := maxAlternatingSum(nums, k)

fmt.Println(result)

}

Python齐备代码如下:

.

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

from typing import List

import bisect

class Fenwick:

"""树状数组,维持前缀大值(1-indexed)"""

def __init__(self, n: int):

self.tree = [0] * (n + 1)

self.n = n

def update(self, i: int, val: int) -> None:

"""将位置 i 的值新为 max(tree[i], val)"""

while i

if val > self.tree[i]:

self.tree[i] = val

i += i & -i

def pre_max(self, i: int) -> int:

"""查询 [1, i] 中的大值"""

res = 0

while i > 0:

if self.tree[i] > res:

res = self.tree[i]

i &= i - 1

return res

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

# 破裂化:获取去重排序后的数值

sorted_nums = sorted(set(nums))

m = len(sorted_nums)

# 两个树状数组:

# inc 维持 f_inc(以递加扫尾的瓜代子序列大和)

# dec 维持 f_dec(以递减扫尾的瓜代子序列大和)

inc = Fenwick(m)

dec = Fenwick(m)

n = len(nums)

f_inc = [0] * n

f_dec = [0] * n

ans = 0

for i, x in enumerate(nums):

# 独一当下标距离至少为 k 时,才将 i-k 的气象加入树状数组

if i >= k:

j_prev = nums[i - k] # 之前一经替换为破裂化索引

inc.update(m - j_prev, f_inc[i - k])

dec.update(j_prev + 1, f_dec[i - k])

# 现时元素破裂化

j = bisect.bisect_left(sorted_nums, x)

nums[i] = j # 替换为索引,供后续使用

# 狡计以现时元素扫尾的两种气象

# f_inc: 之前递减扫尾,且前个数

f_inc_i = dec.pre_max(j) + x

# f_dec: 之前递加扫尾,且前个数 > 现时数

f_dec_i = inc.pre_max(m - 1 - j) + x

f_inc[i] = f_inc_i

f_dec[i] = f_dec_i

if f_inc_i > ans:

ans = f_inc_i

if f_dec_i > ans:

ans = f_dec_i

return ans

if __name__ == "__main__":

nums = [5, 4, 2]

k = 2

result = max_alternating_sum(nums, k)

print(result)

C++齐备代码如下:

.

#include

#include

#include

using namespace std;

class Fenwick {

vector tree;

public:

Fenwick(int n) : tree(n + 1, 0) {}

// 新位置 i(1-indexed)的值为 max(tree[i], val)

void update(int i, long long val) {

while (i

tree[i] = max(tree[i], val);

i += i & -i;

}

}

// 查询前缀 [1, i] 的大值

long long preMax(int i) const {

long long res = 0;

while (i > 0) {

res = max(res, tree[i]);

i &= i - 1;

}

return res;

}

};

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

// 破裂化

vector sorted = nums;

sort(sorted.begin, sorted.end);

sorted.erase(unique(sorted.begin, sorted.end), sorted.end);

int m = sorted.size;

int n = nums.size;

vector fInc(n, 0), fDec(n, 0); // 防护运行化为 0(空子序列和为 0)

Fenwick inc(m), dec(m); // 里面数组大小为 m+1,撑抓 1..m 索引

long long ans = 0;

for (int i = 0; i

int x = nums[i];

// 距离至少 k 时,将 i-k 的气象加入树状数组

if (i >= k) {

int j_prev = nums[i - k]; // 之前已替换为破裂化索引

inc.update(m - j_prev, fInc[i - k]);

dec.update(j_prev + 1, fDec[i - k]);

}

// 现时元素的破裂化索引

int j = lower_bound(sorted.begin, sorted.end, x) - sorted.begin;

nums[i] = j; // 替换原值,后续径直使用索引

// 气象出动

fInc[i] = dec.preMax(j) + x; // 之前递减扫尾,且前个数

fDec[i] = inc.preMax(m - 1 - j) + x; // 之前递加扫尾,且前个数 > 现时数

ans = max({ans, fInc[i], fDec[i]});

}

return ans;

}

int main {

vector nums = {5, 4, 2};

int k = 2;

long long result = maxAlternatingSum(nums, k);

cout

return 0;

}

·

咱们笃信东谈主工智能为庸碌东谈主提供了种“增强器具”,并勉力于共享全位的AI常识。在这里,您不错找到新的AI科普著作、器具评测、升迁率的消散以及行业知悉。

宽宥暖热“福大大架构师逐日题”,发音信可赢得口试府上,让AI助力您的将来发展。邮箱:215114768@qq.com相关词条:玻璃棉     塑料挤出机厂家     钢绞线    管道保温    PVC管道管件粘结胶

1.本网站以及本平台支持关于《新广告法》实施的“极限词“用语属“违词”的规定,并在网站的各个栏目、产品主图、详情页等描述中规避“违禁词”。
2.本店欢迎所有用户指出有“违禁词”“广告法”出现的地方,并积极配合修改。
3.凡用户访问本网页,均表示默认详情页的描述阿坝储罐保温施工,不支持任何以极限化“违禁词”“广告法”为借口理由投诉违反《新广告法》,以此来变相勒索商家索要赔偿的违法恶意行为。

Powered by 鑫诚防腐保温工程有限公司 RSS地图 HTML地图

Copyright Powered by站群 © 2025-2034