给你一个正整数数组 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;
};