返回
子数组最大累加和巧解、最长回文子串优雅处理
Android
2024-02-04 15:57:54
引言
子数组最大累加和和最长回文子串,这两大经典算法问题在计算机科学领域中扮演着重要角色。前者用于解决一维数组中最大连续子数组和的问题,后者用于寻找字符串中的最长回文子串。今天,我们将在本文中探讨巧妙高效的解决方案,助您攻克这两个难题。
NC19 子数组的最大累加和问题
问题
给定一个数组,求出其所有子数组中最大累加和。
算法思想
子数组最大累加和问题的经典解法是动态规划 。我们定义状态dp[i]
表示以第i
个元素结尾的子数组的最大累加和。那么状态转移方程为:
dp[i] = max(dp[i-1] + nums[i], nums[i])
其中nums
为输入数组。
时间复杂度:O(n) ,其中n
为数组长度。
代码实现
def max_subarray_sum(nums):
dp = [0] * len(nums)
dp[0] = nums[0]
for i in range(1, len(nums)):
dp[i] = max(dp[i-1] + nums[i], nums[i])
return max(dp)
NC17 最长回文子串
问题
给定一个字符串,求出其最长的回文子串。
算法思想
最长回文子串问题的经典解法是Manacher算法 。该算法利用一个处理过的字符串来巧妙地处理回文子串问题。我们定义一个新的字符串s
,将原字符串t
中的每个字符插入到s
中,并在每个字符之间插入一个分隔符(例如#
)。
时间复杂度:O(n) ,其中n
为原字符串长度。
代码实现
def longest_palindrome(s):
# 构建处理过的字符串
t = "#" + "#".join(s) + "#"
# 回文半径数组
p = [0] * len(t)
# 中心和右边界
center = right = 0
# 最长回文子串长度和起始位置
max_len = 0
start = 0
for i in range(1, len(t)):
# 计算当前位置的回文半径
mirror = 2 * center - i
if i < right:
p[i] = min(right - i, p[mirror])
# 扩展回文半径
while i - p[i] - 1 >= 0 and i + p[i] + 1 < len(t) and t[i - p[i] - 1] == t[i + p[i] + 1]:
p[i] += 1
# 更新中心和右边界
if i + p[i] > right:
center = i
right = i + p[i]
# 更新最长回文子串信息
if p[i] > max_len:
max_len = p[i]
start = (i - max_len) // 2
return s[start:start+max_len]
结语
子数组最大累加和和最长回文子串,这两大算法问题在实际应用中有着广泛的应用场景。通过巧妙高效的算法,我们可以轻松解决这些难题,为计算机科学的进步添砖加瓦。