携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第 19 天,点击查看活动详情
题目描述
给定一个长度为n的数组arr,数组中的元素由0~n-1组成,要求按照要求分割数组,返回数组能分割成的最大子数组的数目。
要求:将arr分割成若干子数组,对每个子数组进行排序后再将各个子数组进行合并,所得的数组与原数组排序后的顺序相同。
例1:输入:arr=[0,2,1,3,6,5,4] 输出:4
解释:可以将arr分割成子数组:[0,2,1]、[3]、[6,5,4]。对各个子数组进行排序后可得[0]、[1,2]、[3]、[4,5,6]。将排序后的数组合并后为[0,1,2,3,4,5,6]与原数组排序后的结果相同。
例2:输入:arr=[4,2,3,1,0] 输出:1
解释:只能将arr作为划分的子数组才能满足要求。
原题地址:769. 最多能完成排序的块
解题思路
因为题中给的数组中元素不是重复的,由0~n-1组成,所以在排序后arr[i]元素应该为i,元素i所在的位置就是索引i。我们应该用一个变量维护当前遍历元素之前的最大值,当前的位置索引如果等于之前维护的最大值,说明当前位置就是最大值所在的位置,就说明可以划分的子数组的位置可以+1。
例如例1中arr=[0,2,1,3,6,5,4]。当维护到索引0时,最大值为0,所以[0]可以划分成一个子数组。当维护到索引2时最大值为2,所以[2,1]可以划分为一个子数组。当维护到索引3时最大值为3,所以[3]可以划分为一个子数组。当维护到索引6时最大值为6,所以[6,5,4]可以划分为一个子数组。
实现代码
class Solution {
public:
int maxChunksToSorted(vector<int>& arr) {
// 记录结果、维护最大值
int res=0,ma=0;
// 遍历字符串
for(int i=0;i<arr.size();i++){
// 维护最大值
ma=max(ma,arr[i]);
// 如果当前位置索引号和最大值相等,则结果加1
if(ma==i) res++;
}
return res;
}
};