Leetcode 1021:最佳观光组合(超详细的解法!!!)

版权声明:本文为博主原创文章,未经博主允许不得转载。有事联系:[email protected] https://blog.csdn.net/qq_17550379/article/details/88792543

给定正整数数组 AA[i] 表示第 i 个观光景点的评分,并且两个景点 ij 之间的距离为 j - i

一对景点(i < j)组成的观光组合的得分为(A[i] + A[j] + i - j):景点的评分之和减去它们两者之间的距离。

返回一对观光景点能取得的最高分。

示例:

输入:[8,1,5,2,6]
输出:11
解释:i = 0, j = 2, A[i] + A[j] + i - j = 8 + 5 + 0 - 2 = 11

提示:

  1. 2 <= A.length <= 50000
  2. 1 <= A[i] <= 1000

解题思路

这个问题和之前问题Leetcode 121:买卖股票的最佳时机(最详细的解法!!!)非常类似。只不过我们这里的sellbuy重新思考。我们最后需要将A[i] + A[j] + i - j最大化,也就可以理解为A[i]+iA[j]-j最大化。那么此时的buy就可以理解为buy=max(buy, A[i]+i),而sell可以理解为sell=max(sell, A[j]-j+buy)

最后思考边界问题,我们只需要将sell=0buy=float("-inf")即可。

class Solution:
    def maxScoreSightseeingPair(self, A: List[int]) -> int:
        sell, buy = 0, float('-inf')
        for i, val in enumerate(A):
            sell = max(sell, val - i + buy)
            buy = max(buy, val + i)
        return sell

注意上面的写法,为什么不是这样呢?

buy = max(buy, val + i)
sell = max(sell, val - i + buy)

注意的一个细节就是j>i,也就是先有j再有i,那么我们就需要将sell放到buy的前面(我们之前的问题是先buysell)。

还有一种非常棒的思路,我们每次遍历A中的元素a,对于我们遍历过的元素我们当然知道谁是最大的。例如,[8,1,5,2,6],我们遍历到8,我们当然知道8是那个最大的,接着我们会找第二个数。当我们遍历到1的时候,此时8,距离我们的位置就变成1,也就是说8会变成7,此时我们的和就是1+7,是不是最大的和呢?不知道,还要继续遍历下去。接着找到5,此时8距离52,所以8变成了6,所以此时的和就变成了6+5=1。就这样依次遍历下去,直到所有元素都找完。

class Solution:
    def maxScoreSightseeingPair(self, A: List[int]) -> int:
        cur = res = 0
        for a in A:
            res = max(res, cur + a)
            cur = max(cur, a) - 1
        return res

reference:

https://leetcode.com/problems/best-sightseeing-pair/discuss/260850/JavaC%2B%2BPython-One-Pass

我将该问题的其他语言版本添加到了我的GitHub Leetcode

如有问题,希望大家指出!!!

猜你喜欢

转载自blog.csdn.net/qq_17550379/article/details/88792543