最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++實現(xiàn)LeetCode(768.可排序的最大塊數(shù)之二)

 更新時間:2021年07月12日 15:17:24   作者:Grandyang  
這篇文章主要介紹了C++實現(xiàn)LeetCode(768.可排序的最大塊數(shù)之二),本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下

[LeetCode] 768.Max Chunks To Make Sorted II 可排序的最大塊數(shù)之二

This question is the same as "Max Chunks to Make Sorted" except the integers of the given array are not necessarily distinct, the input array could be up to length 2000, and the elements could be up to 10**8.

Given an array arr of integers (not necessarily distinct), we split the array into some number of "chunks" (partitions), and individually sort each chunk.  After concatenating them, the result equals the sorted array.

What is the most number of chunks we could have made?

Example 1:

Input: arr = [5,4,3,2,1]
Output: 1
Explanation:
Splitting into two or more chunks will not return the required result.
For example, splitting into [5, 4], [3, 2, 1] will result in [4, 5, 1, 2, 3], which isn't sorted.

Example 2:

Input: arr = [2,1,3,4,4]
Output: 4
Explanation:
We can split into two chunks, such as [2, 1], [3, 4, 4].
However, splitting into [2, 1], [3], [4], [4] is the highest number of chunks possible.

Note:

  • arr will have length in range [1, 2000].
  • arr[i] will be an integer in range [0, 10**8].

這道題是之前那道 Max Chunks To Make Sorted 的拓展,那道題說了數(shù)組是[0, n-1]中所有數(shù)字的一種全排列,n為數(shù)組的長度。而這道題的數(shù)字就沒有這種限制,可以是大于n的數(shù)字,也可以有重復的數(shù)字。由于數(shù)字和坐標不再有太多的關聯(lián),所以之前那題中比較數(shù)字和坐標的大小的解法肯定行不通了。我們來看一種十分巧妙的解法,首先我們需要明確的一點是,拆分后的塊兒排序后拼在一起會跟原數(shù)組相同,我們用一個例子來說明:

2  1  4  3  4

1  2  3  4  4

1  2  3  4  4

我們看到第一行是原數(shù)組,第二行是排序后并拼接在了一起的塊兒,不同的顏色代表不同的塊兒,而第三行是直接對原數(shù)組排序后的結(jié)果。仔細觀察可以發(fā)現(xiàn),能形成塊兒的數(shù)字之和跟排序后的數(shù)組的相同長度的子數(shù)組的數(shù)字之和是相同的。比如第一個塊兒是數(shù)字2和1,和為3,而排序后的前兩個數(shù)字為1和2,和也是3,那么我們就知道原數(shù)組的前兩個數(shù)字可以拆成一個塊兒。同理,原數(shù)組中的第三個和第四個數(shù)字分別為4和3,和為7,而排序后的數(shù)組對應位置的數(shù)字之和也是7,說明可以拆分出塊兒。需要注意的是,在累加數(shù)組和的時候有可能會超過整型最大值,所以我們用長整型來保存就可以了。就是這么簡單而暴力的思路,時間復雜度為O(nlgn),主要花在給數(shù)組排序上了。由于本題是 Max Chunks To Make Sorted 的generalized的情況,所以這種解法自然也可以解決之前那道題了,不過就是時間復雜度稍高了一些,參見代碼如下:

解法一:

class Solution {
public:
    int maxChunksToSorted(vector<int>& arr) {
        long res = 0, sum1 = 0, sum2 = 0;
        vector<int> expect = arr;
        sort(expect.begin(), expect.end());
        for (int i = 0; i < arr.size(); ++i) {
            sum1 += arr[i];
            sum2 += expect[i];
            if (sum1 == sum2) ++res;
        }
        return res;
    }
};

這道題的時間復雜度可以優(yōu)化到線性,不過就是需要花點空間。下面這種解法也相當?shù)那擅?,我們需要兩個數(shù)組forward和backward,其中 foward[i] 表示 [0, i] 范圍內(nèi)最大的數(shù)字,而 backward[i] 表示 [i, n-1] 范圍內(nèi)最小的數(shù)字,實際上就是要知道已經(jīng)遍歷過的最大值,和還未遍歷的到的最小值。為啥我們對這兩個值感興趣呢?這是本解法的精髓所在,我們知道可以拆分為塊兒的前提是之后的數(shù)字不能比當前塊兒中的任何數(shù)字小,不然那個較小的數(shù)字就無法排到前面。就像例子1,為啥不能拆出新塊兒,就因為最小的數(shù)字在末尾。那么這里我們能拆出新塊兒的條件就是,當前位置出現(xiàn)過的最大值小于等于之后還未遍歷到的最小值時,就能拆出新塊兒。比如例子2中,當 i=1 時,此時出現(xiàn)過的最大數(shù)字為2,未遍歷到的數(shù)字中最小值為3,所以可以拆出新塊兒,參見代碼如下:

解法二:

class Solution {
public:
    int maxChunksToSorted(vector<int>& arr) {
        int res = 1, n = arr.size();
        vector<int> f = arr, b = arr;   
        for (int i = 1; i < n; ++i) f[i] = max(arr[i], f[i - 1]);   
        for (int i = n - 2; i >= 0; --i) b[i] = min(arr[i], b[i + 1]);
        for (int i = 0; i < n - 1; ++i) {
            if (f[i] <= b[i + 1]) ++res;
        }
        return res;
    }
};

我們可以優(yōu)化一下空間復雜度,因為我們可以在遍歷的過程中維護一個當前最大值curMax,所以就不用一個專門的forward數(shù)組了,但是backward數(shù)組還是要的,參見代碼如下: 

解法三:

class Solution {
public:
    int maxChunksToSorted(vector<int>& arr) {
        int res = 1, n = arr.size(), curMax = INT_MIN;
        vector<int> b = arr;    
        for (int i = n - 2; i >= 0; --i) b[i] = min(arr[i], b[i + 1]);
        for (int i = 0; i < n - 1; ++i) {
            curMax = max(curMax, arr[i]);
            if (curMax <= b[i + 1]) ++res;
        }
        return res;
    }
};

下面這種使用單調(diào)棧Monotonous Stack的解法的題也十分的巧妙,我們維護一個單調(diào)遞增的棧,遇到大于等于棧頂元素的數(shù)字就壓入棧,當遇到小于棧頂元素的數(shù)字后,處理的方法很是巧妙?。菏紫热〕鰲m斣?,這個是當前最大值,因為我們維護的就是單調(diào)遞增棧啊,然后我們再進行循環(huán),如果棧不為空,且新的棧頂元素大于當前數(shù)字,則移除棧頂元素。這步簡直絕了,這里我們單調(diào)棧的元素個數(shù)實際上是遍歷到當前數(shù)字之前可以拆分成的塊兒的個數(shù),我們遇到一個大于棧頂?shù)脑?,就將其壓入棧,suppose其是一個新塊兒的開頭,但是一旦后面遇到小的數(shù)字了,我們就要反過來檢查前面的數(shù)字,有可能我們之前認為的可以拆分成塊兒的地方,現(xiàn)在就不能拆了,舉個栗子來說吧:

比如數(shù)組為 [1 0 3 3 2],我們先把第一個數(shù)字1壓入棧,此時棧為:

stack:1

然后遍歷到第二個數(shù)字0,發(fā)現(xiàn)小于棧頂元素,將棧頂元素1取出存入curMax,此時棧為空了,不做任何操作,將curMax壓回棧,此時棧為:

stack:1

然后遍歷到第三個數(shù)字3,大于棧頂元素,壓入棧,此時棧為:

stack:1,3

然后遍歷到第四個數(shù)字3,等于棧頂元素,壓入棧,此時棧為:

stack:1,3,3

然后遍歷到第五個數(shù)字2,小于棧頂元素,將棧頂元素3取出存入curMax,此時新的棧頂元素3,大于當前數(shù)字2,移除此棧頂元素3,然后新的棧頂元素1,小于當前數(shù)字2,循環(huán)結(jié)束,將curMax壓回棧,此時棧為:

stack:1,3

所以最終能拆為兩個塊兒,即stack中數(shù)字的個數(shù),參見代碼如下:

解法四:

class Solution {
public:
    int maxChunksToSorted(vector<int>& arr) {
        stack<int> st;
        for (int i = 0; i < arr.size(); ++i) {
            if (st.empty() || st.top() <= arr[i]) {
                st.push(arr[i]);
            } else {
                int curMax = st.top(); st.pop();
                while (!st.empty() && st.top() > arr[i]) st.pop();
                st.push(curMax);
            }
        }
        return st.size();
    }
};

到此這篇關于C++實現(xiàn)LeetCode(768.可排序的最大塊數(shù)之二)的文章就介紹到這了,更多相關C++實現(xiàn)可排序的最大塊數(shù)之二內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • C++中頭文件和源文件詳細介紹

    C++中頭文件和源文件詳細介紹

    這篇文章主要介紹了C++中頭文件和源文件詳細介紹的相關資料,需要的朋友可以參考下
    2017-02-02
  • 深入分析C語言分解質(zhì)因數(shù)的實現(xiàn)方法

    深入分析C語言分解質(zhì)因數(shù)的實現(xiàn)方法

    這篇文章主要介紹了深入分析C語言分解質(zhì)因數(shù)的實現(xiàn)方法,作者結(jié)合了ACM題目作為相關拓展,需要的朋友可以參考下
    2015-08-08
  • 純C語言:貪心Prim算法生成樹問題源碼分享

    純C語言:貪心Prim算法生成樹問題源碼分享

    這篇文章主要介紹了貪心Prim算法生成樹問題源碼,有需要的朋友可以參考一下
    2014-01-01
  • C++實現(xiàn)圖書館案例

    C++實現(xiàn)圖書館案例

    這篇文章主要為大家詳細介紹了C++實現(xiàn)圖書館案例,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • C++多線程編程簡單實例

    C++多線程編程簡單實例

    本文給大家分享的是C++多線程編程簡單實例,由于C++本身沒有多線程機制,在windows下我們使用調(diào)用SDK win32 api來實現(xiàn),示例都很簡單,講解的也很詳細,推薦給大家。
    2015-03-03
  • C++實現(xiàn)藍橋杯競賽題目---搭積木

    C++實現(xiàn)藍橋杯競賽題目---搭積木

    這篇文章主要介紹了C++實現(xiàn)藍橋杯競賽題目---搭積木,本篇文章通過題目分析列舉公式進行分析算法,包含詳細的圖文,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • 剖析C++編程當中指針作為函數(shù)參數(shù)的用法

    剖析C++編程當中指針作為函數(shù)參數(shù)的用法

    這篇文章主要介紹了剖析C++編程當中指針作為函數(shù)參數(shù)的用法,是C++入門學習中的基礎知識,需要的朋友可以參考下
    2015-09-09
  • C語言與Lua之間的相互調(diào)用詳解

    C語言與Lua之間的相互調(diào)用詳解

    這篇文章主要給大家介紹了關于C語言與Lua之間的相互調(diào)用的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧。
    2018-01-01
  • OpenCV實現(xiàn)圖像切割功能

    OpenCV實現(xiàn)圖像切割功能

    這篇文章主要為大家詳細介紹了OpenCV實現(xiàn)圖像切割功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-01-01
  • Qt使用Json的項目實踐

    Qt使用Json的項目實踐

    JSON是一種對源自Javascript的對象數(shù)據(jù)進行編碼的格式,但現(xiàn)在被廣泛用作互聯(lián)網(wǎng)上的數(shù)據(jù)交換格式,本文主要介紹了Qt使用Json的項目實踐,詳細的介紹了主要使用的類以及Json實戰(zhàn),感興趣的可以了解一下
    2023-09-09

最新評論

错那县| 宝丰县| 阿合奇县| 丰台区| 玛沁县| 石楼县| 句容市| 武义县| 司法| 凤翔县| 息烽县| 广东省| 江西省| 保定市| 扶风县| 惠东县| 安义县| 根河市| 拉萨市| 榕江县| 拜泉县| 澳门| 通化市| 门源| 榆社县| 保靖县| 兴隆县| 会同县| 古浪县| 五寨县| 安仁县| 吴江市| 陆良县| 迁安市| 永泰县| 浏阳市| 石渠县| 岳普湖县| 敦化市| 连州市| 府谷县|