[M前缀和] lc1014. 最佳观光组合(思维+前缀和+算法优化)

Posted Ypuyu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[M前缀和] lc1014. 最佳观光组合(思维+前缀和+算法优化)相关的知识,希望对你有一定的参考价值。

1. 题目来源

链接:1014. 最佳观光组合

进阶题:[Mdp] lc1937. 扣分后的最大得分(dp优化+前后缀优化+周赛250_3)

2. 题目解析

思维题,算法优化,两次遍历妥妥超时,也没啥二段性可言,没想到是一次遍历啊。

方法一:

  • 简单精心转换:(A[i]+i)+(A[j]-j) 则可以通过一次顺序遍历,用一个数组 maxA[i] 来维护前 i 个位置上 A[i]+i 的最大值。然后在逆序遍历,用一个变量维护后半段 A[j]-j 的最大值,查询 maxA[j] 即可知道当前位置上 A[i]+i 的最大值,累加,每次更新答案最大值即可。
  • 由于需要保证 i<j,所以针对 j 的遍历需要逆向遍历。
  • 两次遍历即可找到答案。
  • 需要保证 i<j,故求最值的时候细节需要注意。维护后 j 个最大值,前半段最大值是 maxA[j - 1]

方法二:

  • 用一个变量维护前半段 A[i]+i 的最大值,直接和当前的 A[j]-j 累加,更新答案,并更新前半段的 A[i]+i 的最大值即可。
  • 这样一次遍历,就能找到答案。

时间复杂度: O ( n ) O(n) O(n)

空间复杂度: O ( 1 ) O(1) O(1)


方法一:

class Solution {
public:
    int maxScoreSightseeingPair(vector<int>& values) {
        int n = values.size();
        vector<int> maxA(n);
        maxA[0] = values[0];
        for (int i = 1; i < n; i ++ ) maxA[i] = max(maxA[i - 1], values[i] + i);

        int res = -1e9, maxB = -1e9;
        for (int i = n - 1; i >= 1; i -- ) {
            maxB = max(maxB, values[i] - i);
            res = max(res, maxA[i - 1] + maxB);
        }

        return res;
    }
};

其实,如果循环从数组下标 1 开始的话,答案和最值都应该赋一个初始值,例如 for(int i = 0; i < n - 1; i ++ ) 这种,当只有一个元素的时候,根本进不去循环,res=-1e9 将直接返回。已经吃了很多次亏了…

class Solution {
public:
    int maxScoreSightseeingPair(vector<int>& values) {
        int n = values.size();
        vector<int> maxA(n);
        maxA[0] = values[0];
        for (int i = 1; i < n; i ++ ) maxA[i] = max(maxA[i - 1], values[i] + i);

        int maxB = values[n - 1] - (n - 1);
        int res = maxA[n - 2] + maxB;
        for (int i = n - 1; i >= 1; i -- ) {
            maxB = max(maxB, values[i] - i);
            res = max(res, maxA[i - 1] + maxB);
        }

        return res;
    }
};

方法二:最优解法了

class Solution {
public:
    int maxScoreSightseeingPair(vector<int>& values) {
        int n = values.size();
        int res = -1e9, a = -1e9;
        for (int i = 0; i < n; i ++ ) {
            res = max(res, a + values[i] - i);
            a = max(a, values[i] + i);
        }

        return res;
    }
};

以上是关于[M前缀和] lc1014. 最佳观光组合(思维+前缀和+算法优化)的主要内容,如果未能解决你的问题,请参考以下文章

[LeetCode]1014. 最佳观光组合

java刷题--1014最佳观光组合

LeetCode每日一题2020.6.17 1014. 最佳观光组合

LeetCode 1014. 最佳观光组合

leetcode-1014-最佳观光组合

[M前缀和] lc525. 连续数组(前缀和+知识理解+思维)