Max Chunks To Make Sorted LT769

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.

Note:

  • arr will have length in range [1, 10].
  • arr[i] will be a permutation of [0, 1, ..., arr.length - 1].


1. Iterate the array, if all the elements on the left are smaller than the elements on the left, there is a new chunk. The first solution use two arrays, leftMax[i] to record the max element ending at i and starting from 0, rightMin[i] to record element starting at i and ending at 0.

Time complexity: O(n)

Space complexity: O(n)

class Solution {
    public int maxChunksToSorted(int[] arr) {
        if(arr == null) return 1;

        int sz = arr.length;
        int[] leftMax = new int[sz];
        int[] rightMin = new int[sz];

        leftMax[0] = arr[0];
        for(int i = 1; i < sz; ++i) {
            leftMax[i] = Math.max(leftMax[i-1], arr[i]);
        }

        rightMin[sz-1] = arr[sz-1];
        for(int i = sz-2; i >= 0; --i) {
            rightMin[i] = Math.min(rightMin[i+1], arr[i]);
        }

        int count = 1;
        for(int i = 0; i < sz-1; ++i) {
            if(leftMax[i] < rightMin[i+1] ) ++count;
        }

        return count;
    }
}

1a. Since we iterate either from left to right or right to left, we do not need two arrays to keep all the previous record and can use one varible to record the max element from the left so far, as long as the max element is smaller than the min element on the right, there is a new chunk

class Solution {
    public int maxChunksToSorted(int[] arr) {
        if(arr == null) return 1;

        int sz = arr.length;
        int[] rightMin = new int[sz];
        rightMin[sz-1] = arr[sz-1];
        for(int i = sz-2; i >= 0; --i) {
            rightMin[i] = Math.min(rightMin[i+1], arr[i]);
        }

        int max = arr[0];
        int count = 1;
        for(int i = 0; i < sz-1; ++i) {
            max = Math.max(max, arr[i]);
            if(max < rightMin[i+1]) ++count;
        }

        return count;
    }
}

1b. Iterate from right to left:

class Solution {
    public int maxChunksToSorted(int[] arr) {
        if(arr == null) return 1;

        int sz = arr.length;
        int[] leftMax = new int[sz];
        leftMax[0] = arr[0];
        for(int i = 1; i < sz; ++i) {
            leftMax[i] = Math.max(leftMax[i-1], arr[i]);
        }

        int rightMin = arr[sz-1];
        int count = 1;
        for(int i = sz-1; i >= 1; --i) {
            rightMin = Math.min(rightMin, arr[i]);
            if(leftMax[i-1] < rightMin) {
                ++count;
            }
        }
        return count;
    }
}

2. Since arr[i] will be a permutation of [0, 1, ..., arr.length - 1], each element is unique and after sorted, arr[i] = i, the elements on the left will be smaller than the elemnts on the right, as long as the max element at index i is arr[i].

Time complexity: O(n)

Space complexity: O(1)

class Solution {
    public int maxChunksToSorted(int[] arr) {
        if(arr == null) return 1;

        int maxSoFar = arr[0];
        int count = 0;
        for(int i = 0; i < arr.length; ++i) {
            maxSoFar = Math.max(maxSoFar, arr[i]);
            if(maxSoFar == i) ++count;
        }

        return count;
    }
}

2a Another slightly optimisation to terminate the loop early if the max element arr[arr.length-1] is found

class Solution {
    public int maxChunksToSorted(int[] arr) {
        if(arr == null) return 1;

        int maxSoFar = arr[0];
        int count = 0;
        for(int i = 0; i < arr.length; ++i) {
            maxSoFar = Math.max(maxSoFar, arr[i]);
            if(maxSoFar == arr.length-1) return count+1;
            if(maxSoFar == i) ++count;
        }

        return count;
    }
}

3. Another way to think, if we consider each chunk, as a range [min, max] ended at max, if the next element is smaller than the previous max, we need to merge the range by poping up the max element of chunks which max element is bigger, we need to include the new element in the poped up chunks, otherwise, push the new max element. The number of elements on the stack means the number of chunks.

[4, 3, 2, 1, 0] -> [4] for 4 -> [4] for 3 -> [4] for 2 -> [4] for 1 -> [0]

[1, 0, 2, 3, 4] -> [1] -> [1] -> [1, 2] -> [1, 2, 3] -> [1, 2, 3, 4]

[1, 2, 0, 3] -> [1] -> [1, 2] -> [2] -> [2, 3]

Time complexity: O(n)

Space complexity: O(n)

class Solution {
    public int maxChunksToSorted(int[] arr) {
        Deque<Integer> maxStack = new LinkedList<Integer>();

        for(int num: arr) {
            if(maxStack.isEmpty() || num > maxStack.peek()) {
                maxStack.push(num);
            }
            else {
                int max = maxStack.peek();
                while(!maxStack.isEmpty() && num < maxStack.peek()) {
                    maxStack.pop();
                }
                maxStack.push(max);
            }
        }

        return maxStack.size();
    }
}

3a It can be observed from the code that we always push the current max as where the range ends.

public class Solution {

    public int maxChunksToSorted(int[] arr) {
        Deque<Integer> maxStack = new LinkedList<Integer>();

        for(int num: arr) {
            int currMax = maxStack.isEmpty()? num: Math.max(num, maxStack.peek());

            while(!maxStack.isEmpty() && num < maxStack.peek()) {
                maxStack.pop();
            }

            maxStack.push(currMax);
        }

        return maxStack.size();
    }
}

4. Another way is to caculate the distance between the current index with the expected sorted index, if the sum is 0, the whole chunk could be a sorted array.

Time complexity: O(n)

Space complexity: O(1)

public class Solution {

    public int maxChunksToSorted(int[] arr) {

        int count = 0, sum = 0;
        for(int i = 0; i < arr.length; ++i) {
            sum += arr[i] - i;
            if(sum == 0) ++count;
        }
       return count;
    }

}

原文地址:https://www.cnblogs.com/taste-it-own-it-love-it/p/10357864.html

时间: 2024-07-30 16:01:49

Max Chunks To Make Sorted LT769的相关文章

[LeetCode] Max Chunks To Make Sorted II 可排序的最大块之二

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

Max Chunks To Make Sorted II LT768

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

768. Max Chunks To Make Sorted II

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

Max Chunks To Make Sorted

LeetCode 768. Max Chunks To Make Sorted I 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

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 m

[LeetCode] 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 m

【LeetCode】数组

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica } [1]Two Sum [4]Median of Two Sorted Arrays [11]Container With Most Water [15]3Sum [16]3Sum Closest [18]4Sum [26]Remove Duplicates from Sorted Array [27]Remove Element [31]Next Permutatio

Shortest Unsorted Continuous Subarray LT581

Given an integer array, you need to find one continuous subarray that if you only sort this subarray in ascending order, then the whole array will be sorted in ascending order, too. You need to find the shortest such subarray and output its length. E

day05匿名函数,内置函数,二分法,递归,模块

yield作为表达式来使用的方式 #grep -rl 'python /root """ 查找root下文件中含有python的文件 """ import os def init(func): def wrapper(*args,**kwargs): g=func(*args,**kwargs) next(g) return g return wrapper @init def search(target): while True: search