https://leetcode-cn.com/problems/best-sightseeing-pair/
Given an array A of positive integers, A[i] represents the value of the i-th sightseeing spot, and two sightseeing spots i and j have distance j - i between them.
The score of a pair (i < j) of sightseeing spots is (A[i] + A[j] + i - j) : the sum of the values of the sightseeing spots, minus the distance between them.
Return the maximum score of a pair of sightseeing spots.
Example 1:
Input: [8,1,5,2,6]
Output: 11
Explanation: i = 0, j = 2, A[i] + A[j] + i - j = 8 + 5 + 0 - 2 = 11
Note:
2 <= A.length <= 50000
1 <= A[i] <= 1000
暴力超时法。。。:
public int getScore(int[] A,int i, int j){
return A[i]+A[j]+i-j;
}
public int maxScoreSightseeingPair(int[] A) {
if(A == null) return 0;
int biggestScore = 0;
for(int i = 0; i < A.length - 1; i++){
for(int j = i+1 ; j < A.length; j++){
int num = getScore(A,i,j);
if(biggestScore < num)biggestScore = num;
}
}
return biggestScore;
}
优化一:对于观光点得分A[i]+A[j]+i-j,考虑到A[i]与i、A[j]与j 值固定,可以将式子拆分为 A[i]+i 与 A[j]-j ,简化成一层for循环:
public int maxScoreSightseeingPair(int[] A) {
if(A == null) return 0;
int biggestScore = 0;
//初始化第一次循环数据,设定maxI为i组合的最大值
int maxI = A[0] + 0;
for (int j = 1; j < A.length; ++j) {
int tempJ = A[j] - j;
//遍历出 j组合+maxI的最大值 赋值给biggestScore
biggestScore = Math.max(biggestScore, maxI + tempJ);
//更新i组合的值
maxI = Math.max(maxI, A[j] + j);
}
return biggestScore;
}
优化二:对于观光点得分A[i]+A[j]+i-j,对于i-j,在遍历j时,随着j的增大(i - j)每次-1, ;
public int maxScoreSightseeingPair(int[] A) {
int biggestScore = 0;
int maxI = 0;
for (int tempJ : A) {
biggestScore = Math.max(biggestScore, maxI + tempJ);
//maxI值为maxI'-1 或tempJ-1,如果初始的maxI已经是最大值,遍历只需要不断-1即可;
//若之后出现更大的值,直接跳到对应位置,从该位置重新进行-1操作;
//直到找到距离maxI近(减的值少)且tempJ大的j:biggestScore = maxI - n + tempJ
maxI = Math.max(maxI, tempJ) - 1;
}
return biggestScore;
}