网易首页 > 网易号 > 正文 申请入驻

2026-10-10:回文子数组求和。用go语言,现有一个整数序列。请从其中选出若干个位置相邻且数量不为零的连续元素,要求这段元素按原顺序读

0
分享至

2026-10-10:回文子数组求和。用go语言,现有一个整数序列。请从其中选出若干个位置相邻且数量不为零的连续元素,要求这段元素按原顺序读和按相反顺序读完全一致,也就是具有回文性质。对于所有满足这种条件的连续片段,计算其中所有整数相加的结果,并找出可能得到的最大值。最后返回这个最大和。

1 <= nums.length <= 100000。

1 <= nums[i] <= 1000000000。

输入: nums = [10,10]。

输出: 20。

解释:

整个数组 [10,10] 是回文子数组。因此,最大元素和为 10 + 10 = 20。

题目来自力扣3985。

大体步骤如下:

第一步,把原数组改造成一个扩展数组。
原数组中的元素都是正整数,代码在每两个原元素之间以及两端插入一个特殊分隔值 -1,使得原来长度为奇数和偶数的回文片段,在扩展数组里都变成以某个位置为中心的奇回文。扩展数组开头放一个 -2,结尾放 -1 和 -3 作为哨兵,用来避免边界判断,并保证向两边扩展时一定会停止。这样原数组下标和扩展数组下标之间形成固定对应关系,原数组的连续片段可以映射到扩展数组中的回文区间。

第二步,计算扩展数组中每个中心的最长回文半径。
代码维护一个 halfLen 数组,其中 halfLen[i] 表示以扩展数组第 i 个位置为中心时,最长的回文半径。这个半径决定了扩展数组中回文覆盖的闭区间是左端 i - halfLen[i] + 1,右端 i + halfLen[i] - 1。
为了加速计算,使用 Manacher 算法的思想:维护当前已经找到的、右边界最靠右的回文中心 boxM,以及它的右边界再右移一位的位置 boxR。遍历每个可能的中心 i 时,如果 i 还在 boxR 的左边,就利用它关于 boxM 的对称点 i' 来初步确定回文半径。具体是取对称点的回文半径和 boxR - i 中较小的那个作为初始半径。然后从这个初始半径继续向两边暴力比较,只要两边字符相同,半径就加一,并更新 boxM 和 boxR。因为 boxR 只会不断向右移动,所以虽然内部有暴力扩展,但总扩展次数是线性的。

第三步,预处理原数组的前缀和。
代码建立一个前缀和数组 sum,其中 sum[0] 为 0,sum[k+1] 表示原数组前 k+1 个元素的和。这样任意原数组闭区间 [L, R] 的元素和都可以用 sum[R+1] - sum[L] 在常数时间内算出。由于元素值可能很大,累加结果需要用 64 位整数保存。

第四步,枚举所有回文中心,求对应原数组回文片段的和,并取最大值。
对于扩展数组中的每个中心 i,取出它的最长回文半径 hl。根据扩展数组和原数组的下标转换关系,这个回文片段对应到原数组中的闭区间是:左端为 (i - hl) / 2,右端为 (i + hl) / 2 - 2。
于是该区间的元素和就是 sum[(i + hl) / 2 - 1] - sum[(i - hl) / 2]。代码用这个和不断更新答案,最终保留最大值。
因为题目保证原数组元素都是正数,所以对于同一个中心来说,最长的回文片段一定包含所有更短的回文片段,且元素和更大,因此只需要检查每个中心的最长回文即可。

举例来说,输入 nums = [10, 10]。扩展数组构造后,能够找到一个覆盖两个 10 的回文片段,它对应原数组区间 [0, 1],元素和为 10 + 10 = 20,所以最终输出 20。

总的时间复杂度:
构造扩展数组、Manacher 计算回文半径、建立前缀和、枚举所有中心,这些步骤都是线性的。因此总时间复杂度是 O(n),其中 n 是原数组 nums 的长度。

总的额外空间复杂度:
扩展数组、回文半径数组 halfLen、前缀和数组 sum 的长度都与 n 成正比,因此总额外空间复杂度是 O(n)。

Go完整代码如下:

package main

import (
"fmt"
)

func getSum(s []int) (ans int64) {
// 将 s 改造为 t,这样就不需要分 len(s) 的奇偶来讨论了,因为新数组 t 的每个回文子数组都是奇回文子数组(都有回文中心)
// s 和 t 的下标转换关系:
// (si+1)*2 = ti
// ti/2-1 = si
// ti 为偶数(2,4,6,...)对应 s 中的奇回文子数组
// ti 为奇数(3,5,7,...)对应 s 中的偶回文子数组
t := append(make([]int, 0, len(s)*2+3), -2)
for _, c := range s {
t = append(t, -1, c)
}
t = append(t, -1, -3)

// 定义一个奇回文子数组的回文半径=(长度+1)/2,即保留回文中心,去掉一侧后的剩余子数组的长度
// halfLen[i] 表示在 t 上的以 t[i] 为回文中心的最长回文子数组的回文半径
// 具体地,闭区间 [i-halfLen[i]+1, i+halfLen[i]-1] 是 t 上的一个回文子数组
// 由于 t 中回文子数组的首尾元素一定是 -1,根据下标转换关系,
// 可以得到其在 s 中对应的回文子数组的区间为 [(i-halfLen[i])/2, (i+halfLen[i])/2-2],用这个结论去计算子数组和
halfLen := make([]int, len(t)-2)
halfLen[1] = 1
// boxR 表示当前右边界下标最大的回文子数组的右边界下标+1(初始化成任意 <= 0 的数都可以)
// boxM 为该最大回文子数组的中心位置,二者的关系为 boxR = boxM + halfLen[boxM]
boxM, boxR := 0, 0
for i := 2; i < len(halfLen); i++ { // 循环的起止位置对应着原数组的首尾元素
hl := 1
if i < boxR {
// 记 i 关于 boxM 的对称位置 i'=boxM*2-i
// 若以 i' 为中心的最长回文子数组范围超出了以 boxM 为中心的回文子数组的范围(即 i+halfLen[i'] >= boxR)
// 则 halfLen[i] 应先初始化为已知的回文半径 boxR-i,然后再继续暴力匹配
// 否则 halfLen[i] 与 halfLen[i'] 相等
hl = min(halfLen[boxM*2-i], boxR-i)
}
// 暴力扩展
// 算法的复杂度取决于这部分执行的次数
// 由于扩展之后 boxR 必然会更新(右移),且扩展的的次数就是 boxR 右移的次数
// 因此算法的复杂度 = O(len(t)) = O(len(s))
for t[i-hl] == t[i+hl] {
hl++
boxM, boxR = i, i+hl
}
halfLen[i] = hl
}

sum := make([]int64, len(s)+1)
for i, x := range s {
sum[i+1] = sum[i] + int64(x)
}

for i := 2; i < len(halfLen); i++ {
hl := halfLen[i]
// 见上面注释
ans = max(ans, sum[(i+hl)/2-1]-sum[(i-hl)/2])
}
return
}

func main() {
nums := []int{10, 10}
result := getSum(nums)
fmt.Println(result)
}

Python完整代码如下:

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

from typing import List

def get_sum(nums: List[int]) -> int:
n = len(nums)

# 构造扩展数组 t
t = [-2]
for x in nums:
t.extend([-1, x])
t.extend([-1, -3])

# half_len[i] 表示以 t[i] 为中心的最长回文半径
half_len = [0] * (len(t) - 2)
half_len[1] = 1

box_m, box_r = 0, 0

for i in range(2, len(half_len)):
hl = 1
if i < box_r:
hl = min(half_len[box_m * 2 - i], box_r - i)

while t[i - hl] == t[i + hl]:
hl += 1
box_m, box_r = i, i + hl

half_len[i] = hl

# 前缀和
prefix = [0] * (n + 1)
for i, x in enumerate(nums):
prefix[i + 1] = prefix[i] + x

ans = 0
for i in range(2, len(half_len)):
hl = half_len[i]
ans = max(ans, prefix[(i + hl) // 2 - 1] - prefix[(i - hl) // 2])

return ans

if __name__ == "__main__":
nums = [10, 10]
result = get_sum(nums)
print(result)

C++完整代码如下:

  




long long getSum(const std::vector& s) {
// 将 s 改造为 t,这样就不需要分 len(s) 的奇偶来讨论了,
// 因为新数组 t 的每个回文子数组都是奇回文子数组(都有回文中心)
// s 和 t 的下标转换关系:
// (si + 1) * 2 = ti
// ti / 2 - 1 = si
// ti 为偶数(2,4,6,...)对应 s 中的奇回文子数组
// ti 为奇数(3,5,7,...)对应 s 中的偶回文子数组
std::vector t;
t.reserve(s.size() * 2 + 3);
t.push_back(-2);
for (int c : s) {
t.push_back(-1);
t.push_back(c);
}
t.push_back(-1);
t.push_back(-3);

// halfLen[i] 表示在 t 上的以 t[i] 为回文中心的最长回文子数组的回文半径
// 闭区间 [i - halfLen[i] + 1, i + halfLen[i] - 1] 是 t 上的一个回文子数组
// 由于 t 中回文子数组的首尾元素一定是 -1,根据下标转换关系,
// 可以得到其在 s 中对应的回文子数组区间为:
// [(i - halfLen[i]) / 2, (i + halfLen[i]) / 2 - 2]
std::vector halfLen(t.size() - 2);
halfLen[1] = 1;

// boxR 表示当前右边界下标最大的回文子数组的右边界下标 + 1
// boxM 为该最大回文子数组的中心位置,关系为 boxR = boxM + halfLen[boxM]
int boxM = 0, boxR = 0;

for (int i = 2; i < (int)halfLen.size(); ++i) {
int hl = 1;

if (i < boxR) {
// 记 i 关于 boxM 的对称位置 i' = boxM * 2 - i
// 若以 i' 为中心的最长回文子数组范围超出了以 boxM 为中心的回文子数组范围,
// 则 halfLen[i] 先初始化为已知的回文半径 boxR - i,然后再继续暴力匹配;
// 否则 halfLen[i] 与 halfLen[i'] 相等
hl = std::min(halfLen[boxM * 2 - i], boxR - i);
}

// 暴力扩展
while (t[i - hl] == t[i + hl]) {
++hl;
boxM = i;
boxR = i + hl;
}

halfLen[i] = hl;
}

// 前缀和
std::vector sum(s.size() + 1, 0);
for (int i = 0; i < (int)s.size(); ++i) {
sum[i + 1] = sum[i] + s[i];
}

long long ans = 0;
for (int i = 2; i < (int)halfLen.size(); ++i) {
int hl = halfLen[i];
ans = std::max(ans, sum[(i + hl) / 2 - 1] - sum[(i - hl) / 2]);
}

return ans;
}

int main() {
std::vector nums = {10, 10};
long long result = getSum(nums);
std::cout << result << std::endl;
return0;
}

我们相信人工智能为普通人提供了一种“增强工具”,并致力于分享全方位的AI知识。在这里,您可以找到最新的AI科普文章、工具评测、提升效率的秘籍以及行业洞察。 欢迎关注“福大大架构师每日一题”,发消息可获得面试资料,让AI助力您的未来发展。

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
“刹车踏板断裂”事件,他们是被啪啪打脸啊……

“刹车踏板断裂”事件,他们是被啪啪打脸啊……

麦杰逊
2026-10-13 22:07:00
突发!霍华德首秀,怒喷詹姆斯,示好76人……

突发!霍华德首秀,怒喷詹姆斯,示好76人……

体育新角度
2026-10-13 13:55:42
人民日报:中国消费增长“慢”下来了吗?还有挖潜空间吗?

人民日报:中国消费增长“慢”下来了吗?还有挖潜空间吗?

澎湃新闻
2026-10-13 07:24:03
特朗普前顾问警告:若特朗普进行政治干预,可能在乌克兰造成“严大的破坏”

特朗普前顾问警告:若特朗普进行政治干预,可能在乌克兰造成“严大的破坏”

阿尔卑斯瞭望
2026-10-13 19:24:13
5名中国籍男子在泰实施抢劫 泰国警方:预谋超一月,涉案金额约合3700万泰铢

5名中国籍男子在泰实施抢劫 泰国警方:预谋超一月,涉案金额约合3700万泰铢

封面新闻
2026-10-12 20:49:10
章子怡在法国哭到捂嘴,这套“不修边幅”的造型反倒打了场漂亮仗

章子怡在法国哭到捂嘴,这套“不修边幅”的造型反倒打了场漂亮仗

情感大头说说
2026-10-13 19:26:31
吃饭七分饱被推翻了?医生:老人过了75岁,吃饭尽量要做到这6点

吃饭七分饱被推翻了?医生:老人过了75岁,吃饭尽量要做到这6点

垚垚分享健康
2026-10-13 22:00:09
养了这么多年,一觉醒来团灭!全国多地鱼友中招,有人损失上万元,竟是被一块插排“背刺”……商家:系黑客恶意攻击,已紧急封堵漏洞

养了这么多年,一觉醒来团灭!全国多地鱼友中招,有人损失上万元,竟是被一块插排“背刺”……商家:系黑客恶意攻击,已紧急封堵漏洞

都市快报橙柿互动
2026-10-12 22:16:39
消失12年后,56岁周杰现状曝光,每天只吃一顿饭,至今未婚未育

消失12年后,56岁周杰现状曝光,每天只吃一顿饭,至今未婚未育

娱妮啵啵啊
2026-10-10 15:03:44
挪威张维为,来抢瑞士张维为的市场了

挪威张维为,来抢瑞士张维为的市场了

黔有虎
2026-10-13 11:30:33
科学家警告:厄尔尼诺现象将迅速变得致命,迎来前所未有的转折点!

科学家警告:厄尔尼诺现象将迅速变得致命,迎来前所未有的转折点!

凉州辞
2026-10-13 08:10:05
赖清德,可能成为新中国历史上,唯一在任内出事的台湾地区领导人

赖清德,可能成为新中国历史上,唯一在任内出事的台湾地区领导人

混沌录
2026-10-13 09:50:37
开播一天拿下热度冠军!观众盛赞:首集就欲罢不能

开播一天拿下热度冠军!观众盛赞:首集就欲罢不能

小椰的奶奶
2026-10-13 02:16:05
郭士强后悔吗?季前赛狂轰84分,昔日“最强高中生”或成下一个丁彦雨航

郭士强后悔吗?季前赛狂轰84分,昔日“最强高中生”或成下一个丁彦雨航

大卫的篮球故事
2026-10-13 20:34:25
广东男篮赞助商:新赛季期待能冲进四强,挺进决赛,力争总冠军

广东男篮赞助商:新赛季期待能冲进四强,挺进决赛,力争总冠军

狼叔评论
2026-10-13 16:56:03
上海高架黑色物体随机砸车 目击者:看清后很害怕

上海高架黑色物体随机砸车 目击者:看清后很害怕

看看新闻Knews
2026-10-13 21:19:43
昔日貌美校花被丈夫养至330斤,睡塌两张床,丈夫坦言怕她被抢走

昔日貌美校花被丈夫养至330斤,睡塌两张床,丈夫坦言怕她被抢走

老娱记啊
2026-10-13 15:12:28
俄军对乌克兰实施集群打击

俄军对乌克兰实施集群打击

新京报
2026-10-13 17:30:22
大家心心念念的秦主任素颜照,来了!

大家心心念念的秦主任素颜照,来了!

笔杆论道
2026-10-12 08:58:03
解放军拒出兵后,沙特马上退出中国项目,看他惨状发现,路走窄了

解放军拒出兵后,沙特马上退出中国项目,看他惨状发现,路走窄了

明天见灌装冰块
2026-10-13 20:10:12
2026-10-13 22:55:00
moonfdd incentive-icons
moonfdd
福大大架构师每日一题
1511文章数 83关注度
往期回顾 全部

科技要闻

扎克伯格宣布追上OpenAI!Meta新模型亮相

头条要闻

黄奇帆被查:早年在上海工作 2016年卸任重庆市市长

头条要闻

黄奇帆被查:早年在上海工作 2016年卸任重庆市市长

体育要闻

走调的歌声里全是感情 最好的郑钦文尚未登场

娱乐要闻

谭松韵亲自解答兰香结局遗憾

财经要闻

"黑医师"产业链调查:不学医竟能"拿证"

汽车要闻

豪华智能全拉满 比亚迪大汉不止旗舰级舒适

态度原创

本地
亲子
时尚
教育
公开课

本地新闻

这个十一,林都伊春彻底出圈!

亲子要闻

每个孩子来到这个世界,都是自带“干粮”的!

钟楚曦: 两处人间

教育要闻

少先队队歌诞生地,唱响《我们是共产主义接班人》

公开课

李玫瑾:为什么性格比能力更重要?

无障碍浏览 进入关怀版