亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

數據結構如何將復雜度從O(n^3)殺到O(n)

發布時間:2021-12-21 11:56:23 來源:億速云 閱讀:128 作者:柒染 欄目:大數據

數據結構如何將復雜度從O(n^3)殺到O(n),很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。

最近在LEETCODE上剛好做到這一道題(53.Maximum Subarray)。突然想到數據結構中也有這道題目的例子,于是起興來個總結。

題目: 給你一個數組,讓你求出其中最大的子序列之和。

如:輸入[-2,1,-3,4,-1,2,1,-5,4],其最大的子序列之和為6([4,-1,2,1]).

PS:還記得時間復雜度怎么計算的嗎?

以最壞的情況為基準,數量級至上。嵌套相乘,同級相加。

可能需要說明的函數/定義:

max(a,b) : 返回a,b中較大的那一個。

vector<int>&nums : 傳入一個vector庫,若你對它很陌生,可以暫時把它看做數組(當然它和數組有區別)。

以下所有代碼均只有函數部分。

完整代碼可在: https://github.com/Ckend/GongZhongHao/tree/master/2.27 中查看。

數據結構如何將復雜度從O(n^3)殺到O(n)    

O(n^3)

數據結構如何將復雜度從O(n^3)殺到O(n)

首先,最直接的思維是將每一個子序列的和都求出來。temp的作用是:1.求每個子序列的和,2.每次求完都會和result對比,如果比result大,則將值賦給result。每次這兩個操作結束,temp都會清零

int MaxSubSequenceSum(std::vector<int>&nums){

    int temp = 0 , result = 0;

    for (int i = 0 ; i < nums.size(); ++i) {

        for (int j = i; j < nums.size(); ++j) {

            temp = 0;

            for (int k = i; k <= j; ++k) {

                temp += nums[k];

                result = std::max(result, temp);

            }

        }

    }

    return result;

}

這個算法是絕對正確的。但是效率非常低下。演示如下:

演示并未展現出全部的可能(或許也有點不太準確,最后黃色部分不應該和紫色部分共同前進),但是就如同紫色部分,所有的子序列都會被檢測一遍。

數據結構如何將復雜度從O(n^3)殺到O(n)

我們會思考是否沒必要使用三個循環,也許兩個循環就夠了?

我們從上圖看到,其實FOR2和FOR3都可以進行這種篩選最大子序列的操作,因為他們的行進軌跡其實都是一樣的。于是或許可以刪掉那一個多余的循環。

數據結構如何將復雜度從O(n^3)殺到O(n)    

O(n^2)

數據結構如何將復雜度從O(n^3)殺到O(n)

int MaxSubSequenceSum(std::vector<int>&nums){

    int temp = 0, result = 0;

    for (int i = 0; i < nums.size(); ++i) {

        for (int j = i; j < nums.size(); ++j) {

            temp += nums[j];

            result = std::max(result, temp);

        }

        temp = 0;

    }

    return result;

}

數據結構如何將復雜度從O(n^3)殺到O(n)

雖然說O(n^2)是一個比較可以接受的復雜度。但是如果我們想要更加優化的算法。可能就要往抽象領域里延伸了。

這個O(n)的算法僅僅七行代碼,但是想要理解清楚可沒那么簡單。我們可以從中看出,它與O(n^2)算法的最大區別在于,少了一個循環,并且temp = 0 被 temp = std::max(0, temp) 代替。

為什么我們在O(n^2)的算法中需要兩次循環?因為我們需要把temp清零以保存下一輪的最大值。但是如果我們舍棄這一步操作呢?當序列中全是正數的時候,毋庸置疑,最大子序列就是它自身,于是我們只需要討論兩種情況:

1.序列中有一個以上的正數


當序列中只有一個正數的時候,自然,子序列就是那一個正數。

當序列有大于兩個正數的時候,我們可以確定,最大子序列一定大于0。所以當temp的合小于零的時候,我們可以確定這條序列絕對不是最大子序列,于是將它清零,否則temp不清零。直到遇到真正的最大子序列。


2.序列中全是負數


如果序列中全是負數,那么最大子序列肯定只有一個數。利用result = std::max(result, temp);可以直接判斷出來。

數據結構如何將復雜度從O(n^3)殺到O(n)    

O(n)

數據結構如何將復雜度從O(n^3)殺到O(n)

int MaxSubSequenceSum(std::vector<int>&nums){

    int temp = 0, result = nums[0];

    for (int i = 0; i < nums.size(); ++i) {

        temp += nums[i];

        result = std::max(result, temp);

        temp = std::max(0, temp);

    }

    return result;

}

于是通過這種巧妙的方法,我們成功實現了將算法復雜度優化到O(n)的目標。如果你還是不太明白,我的經驗是要不斷地歸納總結,總是會有一點收獲的。

看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

林西县| 宁海县| 乌兰察布市| 三门峡市| 安陆市| 永顺县| 威海市| 竹山县| 芜湖县| 邹平县| 措美县| 松潘县| 南昌市| 枣强县| 金昌市| 保山市| 永定县| 罗山县| 阿勒泰市| 响水县| 曲靖市| 奉化市| 炎陵县| 台江县| 邢台市| 肃宁县| 图们市| 平远县| 青海省| 塔城市| 绿春县| 潢川县| 德安县| 松溪县| 金山区| 远安县| 邢台县| 慈利县| 苗栗县| 竹溪县| 芒康县|