769. Max Chunks To Make Sorted。

Given an array arr that is a permutation of [0, 1, …, arr.length - 1], 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 = [4,3,2,1,0]
Output: 1
Explanation:
Splitting into two or more chunks will not return the required result.
For example, splitting into [4, 3], [2, 1, 0] will result in [3, 4, 0, 1, 2], which isn’t sorted.

Example 2:

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


给定一个长度为length的数组,这个数组中的元素为[0,1,2…length-1],但是元素并不是按照大小排序的。需要我们将这个数组从前到后最大程度的分块,并且每个块单独进行排序,然后再将各个块按照块的顺序组合起来,组合起来的数组等于原来数组的排序之后的状态。

就如题中的例子: [1,0,2,3,4]。

首先将i去分块,[1,0]、[2]、[3]、[4]。
然后各个块单独排序:[0,1]、[2]、[3]、[4]。
将各个块按顺序起来:[0,1,2,3,4]。
最初的数组进行排序:[0,1,2,3,4]。
两个相等,所以最大块为:4。


既然要对数组进行分块,我们就需要考虑在哪一个点分块合适。唯一需要满足的条件就是分块、排序、连接之后的数组等于原来数组排序。

如果数组是这样的:[4,3,2,1,0],就会发现无论如何分块都不合适,这个数组是呈下降趋势,无从论哪一个点进行划分都不行,因为划分完成进行排序后前面块的元素都会比后面的大,比如从2这个点划分:[4,3,2]、[1,0],排序之后为:[2,3,4]、[0,1]。而原数组排序之后为:[0,1,2,3,4]。

所以说如果前面块中的元素比后面的块大的话,就不可以进行划分。

再看第二个例子: [1,0,2,3,4]。首先可以从0进行划分:[1,0]、[2,3,4]。排序之后的就是[0,1,2,3,4],与原来的数组直接排序一致。但是又发现后面的[2,3,4]可以划分为:[2]、[3]、[4]。后面的元素呈上升趋势,无论怎么划分排序的结果都是一样的,但是为了保证块的个数最多,所以单个元素划分最合适。

所以就能够看出,如果前面的块元素都比后面的小的话,就可以划分。

所以我们就能够得出,如果选择一个点进行划分,那么前面所有元素都要比后面的元素小,否则不能划分。

然后原来数组进行排序之后必定为:[0,1,2,3…length-1]。发现排序完成之后的元素和对应的下标相等。

这两点结合起来:如果分块的话,前面块中所有的元素都要比后面的小,所以说前面块中的最大值要比后面的任意值都小。而且数组排序完之后元素与对应的下标相等,所以如果前面一个块中的最大值排序完之后与其对应的下标相等说明可以分块。

class Solution {
public:
    int maxChunksToSorted(vector<int>& arr) {
        int ans = 0;
        int curMax = 0;

        for(int i=0; i < arr.size(); i++) {
            curMax = max(arr[i],curMax);
            if(curMax == i)// 如果在这个块的范围内,最大值等于下标,说明可以划分
                ans++;
        }
        return ans;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值