求最大不相邻元素和的回溯法时间复杂度及DP回溯最优解构造
嘿,你的思路完全走对了!先给你确认下你提到的例子:输入列表[1,2,3,4,5]对应的memoization数组确实是[1,2,4,6,9],最大和9也完全正确——毕竟最优解是选1、3、5,加起来刚好9,总不能选4和5(相邻了嘛),这点你没搞错~
接下来咱们把你的回溯思路拆解清楚,再补点细节让它更严谨:
回溯的核心逻辑
你从最大和反向推导选中元素的思路非常高效,时间复杂度是O(N),完美适配动态规划的优化方向。具体可以分成这两步来做:
定位最大和的位置
先找到memo数组里的最大值,这里要注意:如果最大值出现多次,得选最右侧的那个位置。比如要是输入是[5,1,1,5],memo数组是[5,5,6,10],最大值10在最后一位,从这里回溯就能找到第一个5和最后一个5的组合;要是输入是[3,2,7,10],memo数组是[3,3,10,13],从最后一位的13回溯,能找到第一个3和最后一个10的组合。反向推导选中元素
拿到最大和max_sum和对应的索引idx后,就可以开始往回找了:- 如果
idx是0:说明第一个元素就是选中的,直接加到结果里就行。 - 如果
idx是1:看哪个元素更大(要是相等的话选哪个都行),加到结果里。 - 当
idx >=2时:- 如果
max_sum == a_list[idx] + memo[idx-2]:说明当前元素被选中了,把它放进结果,然后更新max_sum = max_sum - a_list[idx],同时把idx改成idx-2(毕竟不能选相邻元素)。 - 如果
max_sum == memo[idx-1]:说明当前元素没被选中,直接把idx减1继续回溯。
- 如果
用你的例子
[1,2,3,4,5]演示一遍:- 初始
max_sum=9,idx=4:9等于5加memo[2](5+4=9),所以选中5,max_sum变成4,idx改成2。 - 现在
max_sum=4,idx=2:4等于3加memo[0](3+1=4),选中3,max_sum变成1,idx改成0。 - 最后
idx=0,选中1,结果就是[5,3,1],反转后就是从左到右的选中顺序[1,3,5]。
- 如果
补充小细节
- 如果memo数组里有多个相同的最大值(比如输入
[2,1,2,1,2],memo是[2,2,4,4,6]),从最右侧的最大值开始回溯,能完整找到最优解:选第0、2、4位的2,加起来刚好6。 - 要是你想收集所有可能的最优解(比如有好几个组合都能得到最大和),可以在回溯时加分支判断,但一般情况下咱们只要一个最优解就够了,没必要增加复杂度。
代码示例(Python)
给你写个直观的实现,把动态规划计算和回溯找最优解放一起:
def find_max_non_adjacent_sum(a_list): if not a_list: return 0, [] n = len(a_list) if n == 1: return a_list[0], [a_list[0]] # 构建memo数组 memo = [0] * n memo[0] = a_list[0] memo[1] = max(a_list[0], a_list[1]) for i in range(2, n): memo[i] = max(memo[i-1], memo[i-2] + a_list[i]) max_sum = memo[-1] result = [] idx = n - 1 # 回溯找最优解 while idx >= 0: if idx == 0: result.append(a_list[idx]) break if idx == 1: if a_list[idx] == max_sum: result.append(a_list[idx]) else: result.append(a_list[idx-1]) break if memo[idx] == memo[idx-1]: idx -= 1 else: result.append(a_list[idx]) max_sum -= a_list[idx] idx -= 2 # 反转结果得到从左到右的选中顺序 return memo[-1], result[::-1] # 测试你的例子 a_list = [1,2,3,4,5] max_sum, selected = find_max_non_adjacent_sum(a_list) print(f"最大和: {max_sum}") print(f"选中的元素: {selected}") # 输出: # 最大和: 9 # 选中的元素: [1, 3, 5]
这个代码完全贴合你的思路,跑起来就能得到你想要的结果~
内容的提问来源于stack exchange,提问作者jeffng50
相关产品推荐
相关产品推荐

