數組-最佳觀光組合(力扣1014)

題目鏈接 點我

在這裏插入圖片描述

思路

思路一

看到這種題,我們首先想到的就是暴力解法,雙層循環遍歷,求出對應的值,與最大值進行比較即可。
過程如下:

  1. 數據聲明
    (1)最大分數,用於比較和返回結果
    (2)數組的長度,用於循環條件

  2. 雙層循環,第一層循環從0開始,到len-1結束,第二層循環從1開始到len結束
    每次循環計算出目標值與最大值進行比較更新

代碼
class Solution {
public:
    int maxScoreSightseeingPair(vector<int>& A) {
        int maxScore = 0;
        int len = A.size();
        for(int i=0;i<len-1;i++) {
            for(int j=i+1;j<len;j++) {
                maxScore = max(maxScore, A[i]+A[j]+i-j);
            }
        }
        return maxScore;
    }
};

很明顯,時間複雜度是O(n^2),題目肯定不會這麼簡單地通過地,果然提交後會超時。

思路二

碰到這種多層循環的題我們要想辦法轉換成更少的循環層數,仔細分析要計算的值爲A[i]+i+A[j]-j,我們可以針對每一個A[j]-j,求出以j爲結束時,其的最大值,這時候我們只需要找到A[i]+i的最大值即可,因爲i在j前面,如果我們j從1開始遍歷的話,每次遍歷的過程中就可以更新得到j前面A[i]+i的最大值,不用再一次遍歷。

過程:

  1. 數據聲明
    (1)保存當前最大分數的變量rst
    (2)數組長度len,用於判斷循環結束條件
    (3)保存當前A[i]+i的最大值的變量max_score

  2. 從下標1開始遍歷數組,求出以當前元素爲j元素時,得分的最大值,並以此更新rst(最初max_score的最大值爲下標爲0時的A[i]+i),同時需要通過當前元素更新max_score

  3. rst即爲結果

代碼
class Solution {
public:
    int maxScoreSightseeingPair(vector<int>& A) {
        int rst = 0;
        int len = A.size();
        int max_score = A[0] + 0;
        for(int i=1;i<len;i++) {
            rst = max(rst, max_score+A[i] - i);
            max_score = max(max_score, A[i] + i);
        }
        return rst;
    }
};

很明顯此時時間複雜度變爲了O(n)

總結

1、對於雙層循環暴力解法一定要想辦法將雙層循環變成單層循環
2、對於雙層循環求多個元素最大值的問題(是有一定的重複),我們可以通過求元素較少時的最大值,然後不斷更新最大值,比如求一個數組中兩個元素和的最大值,不能使用排序,我們可以雙層循環,但是也可以通過最大值的另一種求法變成單層循環。本題中,雙層循環其實是,以每個i爲參考點,求j的最大值,然而在求j的最大值過程中,由於元素很多,避免不了有很多重複的過程,然而優化成單層循環是以每個j爲參考點,將j的下標壓縮到較小位置,求i的最大值,這個時候,我們就能在更新j的過程中同時更新j之前i的最大值。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章