资讯详情

资讯详情

LeetCode 1014题解析:最佳观光组合的O(n)解法

1. 问题背景与题目解析这道题目来自LeetCode第1014题Best Sightseeing Pair属于数组类问题中的经典题型。题目描述如下给定一个正整数数组values其中values[i]表示第i个观光景点的评分。你需要选择两个景点i和ji j使得评分总和values[i] values[j] i - j达到最大值。这个评分公式可以理解为两个景点的原始评分之和减去它们之间的距离因为距离越远体验可能越差。举个例子假设values [8,1,5,2,6]那么最佳组合是values[0] values[3] 0 - 3 8 2 - 3 7。2. 暴力解法与复杂度分析最直观的解法是暴力枚举所有可能的(i,j)组合def maxScoreSightseeingPair(values): max_score 0 n len(values) for i in range(n): for j in range(i1, n): current values[i] values[j] i - j max_score max(max_score, current) return max_score这种方法的时间复杂度是O(n²)对于n50000的情况LeetCode的测试用例规模显然会超时。我们需要寻找更优的解法。3. 优化思路与数学变形观察评分公式values[i] values[j] i - j (values[i] i) (values[j] - j)我们可以将问题分解为对于每个j找到i j使得(values[i] i)最大。因为(values[j] - j)对于固定的j是常数所以整个问题转化为维护一个前缀最大值。具体步骤初始化max_prefix values[0] 0初始化max_score 0从j1开始遍历数组计算当前分数current_score max_prefix values[j] - j更新max_score更新max_prefix max(max_prefix, values[j] j)4. 最优解法实现基于上述思路我们可以写出O(n)时间复杂度的解法def maxScoreSightseeingPair(values): max_prefix values[0] 0 # values[i] i max_score 0 for j in range(1, len(values)): max_score max(max_score, max_prefix values[j] - j) max_prefix max(max_prefix, values[j] j) return max_score这个解法只需要一次遍历数组时间复杂度O(n)空间复杂度O(1)完美解决了大规模数据的问题。5. 算法正确性证明为什么这种方法有效关键在于我们维护的max_prefix。对于每个j我们需要的其实是前j-1个元素中(values[i] i)的最大值。通过动态维护这个最大值我们避免了重复计算。数学归纳法证明基础情况j1时max_prefix正确存储了values[0]0归纳假设假设对于jkmax_prefix正确归纳步骤对于jk1我们先用当前的max_prefix计算分数然后更新max_prefix为max(max_prefix, values[k]k)保证了对于jk2时max_prefix仍然正确6. 边界条件与测试用例需要考虑的特殊情况数组长度为2[8,1] → 8 1 0 - 1 8所有元素相同[7,7,7] → 7 7 0 - 1 13递减序列[9,8,7,6] → 9 8 0 - 1 16递增序列[1,2,3,4] → 1 4 0 - 3 2测试代码assert maxScoreSightseeingPair([8,1,5,2,6]) 11 assert maxScoreSightseeingPair([1,2]) 2 assert maxScoreSightseeingPair([7,7,7]) 137. 常见错误与调试技巧新手容易犯的错误初始化max_prefix为0而不是values[0]0从j0开始遍历导致ij的情况更新max_prefix的顺序错误应该先计算分数再更新调试技巧打印中间变量在循环中打印max_prefix和current_score使用小测试用例手动验证检查数组越界情况8. 算法优化与变种这个问题有几个有趣的变种如果要求i和j的距离不超过k可以使用滑动窗口维护最大值如果评分公式改为values[i] * values[j] i - j需要不同的数学变形如果要求找出所有达到最大值的对需要额外存储信息对于原问题还可以进一步优化代码def maxScoreSightseeingPair(values): max_score max_prefix 0 for j in range(len(values)): max_score max(max_score, max_prefix values[j] - j) max_prefix max(max_prefix, values[j] j) return max_score9. 实际应用场景这类问题在实际中有广泛应用旅游路线规划选择最佳的两个观光点股票交易选择买入和卖出时机考虑时间衰减广告投放选择最佳的两个广告位考虑位置影响理解这类问题的解法有助于解决其他类似的最优化问题。10. 刷题建议与学习路径对于LeetCode刷题的建议先尝试暴力解法理解问题本质寻找数学变形或规律考虑动态规划或贪心思路写出优化解法并验证总结类似问题的模式类似题目推荐Best Time to Buy and Sell StockMaximum SubarrayMaximum Product Subarray这个问题的关键在于将原始公式拆分为可独立优化的部分这种分而治之的思想在很多算法问题中都适用。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →