ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Max Chunks To Make Sorted II

2022-08-15 13:01:11  阅读:180  来源: 互联网

标签:arr Max Make stk 区间 mp 数组 Chunks 最大值


Max Chunks To Make Sorted II

You are given an integer array  arr.

We split  arr into some number of chunks (i.e., partitions), and individually sort each chunk. After concatenating them, the result should equal the sorted array.

Return the largest number of chunks we can make to sort the array.

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.

Constraints:

$1 \leq arr.length \leq 2000$
$0 \leq arr[i] \leq {10}^8$

 

解题思路

  对原数组$a$进行排序,得到数组$b$。对数组$a$进行分块,使得数组$a$中的每个块与数组$b$对应的区间是一一对应的。

  可以贪心来做,从前往后枚举来考虑,如果发现枚举到某个数时,$a$的第一个区间里面的所有数与$b$第一个区间里的数相同(每个数出现的频率相同),那么我们就选择这个区间。

  假设我们找到了第一个区间,那么我们的选择有两种,第一种是选择这个区间,第二种不选择这个区间,看看哪种方案包含最优解。假设我们不选择这个区间,未来选择的时候第一个区间就会长一些,如图:

  可以发现如果选择的是红色区间,那么由于红色区间的前部分与第一个黑色区间是一一对应的,因此可以把红色区间分成两个小区间,并且两个小区间也一一对应。因此第二种方案一定不会存在最优解。因此只要我们遇到一个$a,~ b$数组一一对应的区间,我们就直接选择它,然后再往后找下一个区间。

  可以用哈希表来找区间,动态来比较两个集合是否相同。数组$a$中的每个数在哈希表中$+1$,数组$b$中的每个数在哈希表中$-1$,如果发现哈希表为空,说明找到一个区间。

  AC代码如下:

class Solution {
public:
    int maxChunksToSorted(vector<int>& arr) {
        vector<int> backup(arr);
        sort(backup.begin(), backup.end());

        unordered_map<int, int> mp;
        int ret = 0;
        for (int i = 0; i < arr.size(); i++) {
            mp[arr[i]]++, mp[backup[i]]--;
            if (mp[arr[i]] == 0) mp.erase(arr[i]);
            if (mp[backup[i]] == 0) mp.erase(backup[i]);
            if (mp.empty()) ret++;
        }

        return ret;
    }
};

  还可以用单调栈来做。

  用一个栈来维护前面每一个块的最大值,如果来了一个新元素,且比栈顶的值要小,意味着这个元素一定要在栈顶元素的左边,与栈顶在同一个块。因此栈顶元素可以弹出,表示区间还没有完整需要继续更新。直到栈顶元素小于等于这个新元素,再把弹出的区间拼成一个区间压入栈(就是原来栈顶元素的值,即新区间的最大值)。

   放一下LeetCode的题解:

对于已经分好块的数组,若块数大于 $1$,则可以得到以下结论:右边的块的所有数字均大于或等于左边的块的所有数字。考虑这个问题:对于已经分好块的数组,若在其末尾添加一个数字,如何求得新数组的分块方式?

新添加的数字可能会改变原数组的分块方式。如果新添加的数字大于或等于原数组最后一个块的最大值,则这个新添加的数字可以自己形成一个块。如果新添加的数字小于原数组最后一个块的最大值,则它必须融入最后一个块。如果它大于或等于原数组倒数第二个块(如果有)的最大值,那么这个过程可以停止,新数组的分块方式已经求得。否则,它将继续融合原数组倒数第二个块,直到遇到一个块,使得该块的最大值小于或等于这个新添加的数,或者这个数字已经融合了所有块。

上述分析过程中,我们只用到了块的最大值来进行比较,比较过程又是从右到左,符合栈的思想,因此可以用类似单调栈的数据结构来存储块的最大值。

  AC代码如下:

 1 class Solution {
 2 public:
 3     int maxChunksToSorted(vector<int>& arr) {
 4         stack<int> stk;
 5         for (auto &it : arr) {
 6             int t = it;
 7             while (!stk.empty() && stk.top() > it) {
 8                 t = max(t, stk.top());
 9                 stk.pop();
10             }
11             stk.push(t);
12         }
13         return stk.size();
14     }
15 };

 

参考资料

  LeetCode 768. 最多能完成排序的块 II(秋招每日一题):https://www.acwing.com/video/4235/

  最多能完成排序的块 II:https://leetcode.cn/problems/max-chunks-to-make-sorted-ii/solution/zui-duo-neng-wan-cheng-pai-xu-de-kuai-ii-w5c6/

标签:arr,Max,Make,stk,区间,mp,数组,Chunks,最大值
来源: https://www.cnblogs.com/onlyblues/p/16587895.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有