leetcode 768. 最多能完成排序的块 II


768. 最多能完成排序的块 II

难度困难185收藏分享切换为英文接收动态反馈

这个问题和“最多能完成排序的块”相似,但给定数组中的元素可以重复,输入数组最大长度为2000,其中的元素最大为10**8

arr是一个可能包含重复元素的整数数组,我们将这个数组分割成几个“块”,并将这些块分别进行排序。之后再连接起来,使得连接的结果和按升序排序后的原数组相同。

我们最多能将数组分成多少块?

示例 1:

输入: arr = [5,4,3,2,1]
输出: 1
解释:
将数组分成2块或者更多块,都无法得到所需的结果。
例如,分成 [5, 4], [3, 2, 1] 的结果是 [4, 5, 1, 2, 3],这不是有序的数组。 

示例 2:

输入: arr = [2,1,3,4,4]
输出: 4
解释:
我们可以把它分成两块,例如 [2, 1], [3, 4, 4]。
然而,分成 [2, 1], [3], [4], [4] 可以得到最多的块数。 

注意:

  • arr的长度在[1, 2000]之间。
  • arr[i]的大小在[0, 10**8]之间。

解析

根据题目的意思可能明确知道,尽量分块使得最后能分块的个数最多。是一个最值问题,那么就可以使用贪心算法,也就是使得每一个分块的窗口最小。

image-20220813153547212

其实每一次窗口的左边界是确定的(上一次的右边界值),代表的是左闭右开,我们需要确定的是最小的右边界。

这时候通过模拟发现:

某一段能否成为区间是取决于后面的元素,也就是说,区间后面的元素都要 <= 区间内的最大值

/*
    加入可能不能分块的情况,也就是说,分块的排序最后与整体的排序一致
    设计数据结构
    std:::map> data
    第一层索引代表的是数字
    第二层索引代表的是位置
*/

#include 
#include 
#include 
#include 

class Solution {
public:
    int maxChunksToSorted(std::vector& arr) {
        int result = 0;
        int left = 0;
        int right = 0;
        int max_val;
        while(left < arr.size()) {
            int index_val = arr[right];
            // 查看后面是否有比自己更小的值
            max_val = index_val;  // max_val代表当前区间内的最大值
            int tmp_max = max_val;
            // 后面有没有比区间内最大值更小的值了
            for(int i = right + 1; i < arr.size(); ++i) {
                int val = arr[i];
                if(val < max_val) { // 扩大区间
                    left = i;
                    max_val = tmp_max;
                    tmp_max = max_val;
                } else {
                    tmp_max = tmp_max>val? tmp_max : val;
                }
            }
            left = left + 1;
            right = left;
            result++;
        }
        return result;
    }


    void BuildIndex(std::map >& data, std::vector& arr) {
        
        for(int i = 0; i <  arr.size(); ++i) {
            data[arr[i]].insert(i);
        }
    }
};

由于处理结果取决与后面元素的分布情况,适用于栈的处理方式

image-20220813164204130

栈内每一个色块代表的是可能成为的一个组,值代表组内的最大值;当后面有值小于当前的最大值的时候就需要合并。最终的思想就是后面的元素都大于等于当前块内的最大值。

class Solution {
public:
    stack _st;
    int maxChunksToSorted(vector& arr) {
        for(auto& val : arr) {
            if(_st.empty()) {
                _st.push(val);
            } else {
                if(_st.top() <= val) { _st.push(val); } else if(_st.empty()) continue; int tmp_max="_st.top();" while(!_st.empty() && _st.top()> val) {
                        _st.pop();
                    }
                    // 更新最大值
                    _st.push(tmp_max);
                }
            }
        }
        return _st.size();

    }
};

文章作者: ZhongSY
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 ZhongSY !
评论
  目录