leetcode 768. Max Chunks To Make Sorted II(可排序的最大块数II)

本文探讨如何在不保证数组元素唯一的情况下,找出将数组分成多少个部分,使得各部分排序后拼接为整体有序的最少分块数。介绍了两种方法:局部和求和和单调栈策略,并通过实例解析。适用于数组长度高达2000,元素值高达1亿的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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].

769.可排序最大块数类似,分块局部排序,拼在一起后整体要是升序的。不同之处在于数字可以有相同的。

思路:
769题采用下标来判断某数字之前的数字是否全出现过,因为有相同的数字所以不能再用此方法。

方法1: 局部和
能单独分块的部分元素的和 == 排序后相同部分的元素和
出现元素和相等的部分时块数++

保存和时用long型

//1ms
    public int maxChunksToSorted(int[] arr) {
        int n = arr.length;
        int[] sorted = arr.clone();
        Arrays.sort(arr);
        long sum1 = 0;
        long sum2 = 0;
        int result = 0;
        
        for(int i = 0; i < n; i++) {
            sum1 += arr[i];
            sum2 += sorted[i];
            if(sum1 == sum2) {
                result ++;
            } 
        }
        return result;
    }

方法2:单调stack
和769题思路类似,能分块的部分要保证<=当前元素的值都已经出现过。>当前元素的值来时说明块数可+1,<=当前元素的值来时要找到之前比它大的值作为一块。
按照这个思路,>当前元素的值来时压入stack保存,<=当前元素的值来时从stack取出元素直到找到比它大的值,把这个比它大的值压入stack作为某块的结尾。
最后只要看stack中有几个元素,就代表存了几块的结尾。

//3ms
    public int maxChunksToSorted(int[] arr) {
        int n = arr.length;
        Stack<Integer> stack = new Stack<>();
        stack.push(arr[0]);
        int maxNum = 0;
        
        for(int i = 1; i < n; i++) {
            if(arr[i] >= stack.peek()) {
                stack.push(arr[i]);
            } else {
                maxNum = stack.pop();
                while(!stack.empty() && stack.peek() > arr[i]) {
                    stack.pop();
                }
                stack.push(maxNum);
            }
        }
        return stack.size();
    }

参考资料

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝羽飞鸟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值