1014. 最佳观光组合(leetCode每日一题)

1014. 最佳观光组合

给你一个正整数数组 values,其中 values[i] 表示第 i 个观光景点的评分,并且两个景点 i 和 j 之间的 距离 为 j - i

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

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

示例 1:

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

示例 2:

输入:values = [1,2]
输出:2

提示:

  • 2 <= values.length <= 5 * 104
  • 1 <= values[i] <= 1000

解:

根据题意可知:
        1. 选择一对景点

        2. 得分=评分+距离

我们用模拟的思想去看这个问题。

        假如你要去逛景点, 第1个看了,第2个看了。现在得分是不是最高? 不知道,因为后面的还没看。怎么办?继续看一下后面的景点。怎么知道是不是最高的啊? 找一个小本本记录一下最高得分, 当到了下一个景点,重新计算得分,看看我的小本本上和这次计算的得分谁的更大,我小本本上只记录最大得分。就是这么傲娇( ̄^ ̄)。

        怎么计算得分呢? 我们到达了第3个景点。理论上的组合1+3/2+3。我们到达第4个景点,理论上的组合1+4/2+4/3+4。我们每到一个景点把之前的景点都当做潜在对象计算一遍,得到对应的得分(双层循环,暴力破解)。

def maxScoreSightseeingPair(self, values: List[int]) -> int:
    _max = 0
    for i, iv in enumerate(values):
        for j, jv in enumerate(values[i + 1:], start=i + 1):
            _max = max(jv + iv + i - j, _max)
    return _max

        全剧终。。。


        想啥呢?怎么可能这么简单,上面的这些我家7岁的娃都能想到,如果这么简单,他就不会是一个中等难度的题了。

        我们继续代入具体的数据进行模拟。看示例1哈!为啥不看示例2,这一共就2,看个毛线啊!

示例1: 景点评分: [8,1,5,2,6]
我们到达了第1个景点:
    不凑够两个,不能算得分。
我们到达了第2个景点:
	景点1/2得分:1+8+(2-1)=8(1+7)
我们到达了第3个景点:
	景点1/3得分:5+8+(3-1)=11(5+6)
	景点2/3得分:5+1+(3-2)=5(5+0)
我们到达了第4个景点:
	景点1/4得分:2+8+(4-1)=7(2+5)
	景点2/4得分:2+1+(4-2)=1(2+-1)
	景点3/4得分:2+5+(4-3)=6(2+4)
我们到达了第5个景点:
	景点1/5得分:6+8+(5-1)=10(6+4)
	景点2/5得分:6+1+(5-2)=4(6+-2)
	景点3/5得分:6+5+(5-3)=9(6+3)
	景点4/5得分:6+2+(5-4)=7(6+1)

        有啥规律没?针对第1个景点。和2景点组合,权重=7;和3景点组合,权重=6;和4景点组合,权重=5,和5景点组合权重=4;每次递减一个数,正好就是距离的值。
        针对到达景点3的得分最大值是谁呢? 我们从景点2可以计算出来,1的权重是6;2的权重是0;针对到达景点4的得分最大值是谁呢? 会不会是1会不会是2会不会是3?为什么?肯定不会是景点2因为景点2在景点3是进行过计算,累加权重比1要低?会不会是3呢?不知道,需要计算一下3的累加权重和1进行比较。经过计算我们得到还是1的累加权重更高。到达景点5的得分最大值是谁呢?会不会是2,3?为什么?开动小脑筋想一想。肯定不会是2,3了,为啥呢?因为前面已经计算过了1的权重最大,所以只需要比较1和4来计算最大权重。

        上面就是解题步骤,具体怎么做呢? 还是拿出小本本(我们万能的小本本啊!)记录一下当前的最大权重值,拿着最大权重值和当前数值进行比较,谁比较大记录谁,继续遍历,继续比较。

代码很简单,看下面的代码示例:

python代码

def maxScoreSightseeingPair(self, values: List[int]) -> int:
    _max = 0
    _last = values[0]
    for i, v in enumerate(values[1:]):
        _last -= 1
        _max = max(_last + v, _max)
        _last = max(_last, v)
    return _max

java代码

public int maxScoreSightseeingPair(int[] values) {
    int _max = 0;
    int _last = values[0];
    for (int i = 0; i < values.length - 1; i++) {
        int v = values[i + 1];
        _last -= 1;
        _max = _max > _last + v ? _max : _last + v;
        _last = v > _last ? v : _last;
    }
    return _max;
}

javaScript代码

var maxScoreSightseeingPair = function(values) {
    var _max = 0;
    var _last = values[0];
    for(var i=0;i<values.length-1;i++){
        var v = values[i+1];
        _last-=1;
        _max = _max>_last+v?_max:_last+v;
        _last = v>_last?v:_last;
    }
    return _max;
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值