leetcode-pp / 91alg-6-daily-check

91 算法第六期打卡仓库
28 stars 0 forks source link

【Day 6 】2021-12-17 - 768. 最多能完成排序的块 II #10

Open azl397985856 opened 2 years ago

azl397985856 commented 2 years ago

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

入选理由

暂无

题目地址

https://leetcode-cn.com/problems/max-chunks-to-make-sorted-ii/

前置知识

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]之间。

Moin-Jer commented 2 years ago

思路


单调栈

代码


class Solution {
    public int maxChunksToSorted(int[] arr) {
        LinkedList<Integer> stack = new LinkedList<Integer>();
        for(int num : arr) {
            if(!stack.isEmpty() && num < stack.getLast()) {
                int head = stack.removeLast();
                while(!stack.isEmpty() && num < stack.getLast()) stack.removeLast();
                stack.addLast(head);
            }
            else stack.addLast(num);
        }
        return stack.size();
    }
}

复杂度分析


zhangzz2015 commented 2 years ago

前置知识

公司

思路

关键点

代码

C++ Code:


class Solution {
public:
    int maxChunksToSorted(vector<int>& arr) {

        /// increase stack. 

        vector<int> stack; // increase stack. 
        int imax = arr[0]; 
        for(int i=0; i< arr.size(); i++)
        {
           imax = max(imax, arr[i]) ;            
           while(stack.size() && (arr[i]<stack.back()) )
           {
               stack.pop_back(); 
           }
           stack.push_back(imax);  
        }

        return stack.size(); 

    }
};
haixiaolu commented 2 years ago

思路

这题研究了半天也不会, 实在是没辙了, 最后结合单调栈的模版还有官方解答匹配出来的代码

基本就是结合单调栈的递增的概念,pop出栈中小的元素,保留最大的元素,返回的是栈的长度

Code / Python

  def maxChunksToSorted(self, arr: List[int]) -> int:

        # Initialize a stack 
        stack = []

        # loop through all the element in arr 
        for element in arr:

            # find the largest value in the stack and set to -1
            # because stack is increasing

            if stack and stack[-1] > element:

                # set the largest value in stack
                larger = stack[-1]

                # keep the stack increasing (递增)
                while stack and stack[-1] > element: stack.pop()
                stack.append(larger)

            else:
                stack.append(element)

        return len(stack)

复杂度分析

tongxw commented 2 years ago

思路

单调递增栈,遍历数组,保存每个排序块的最大数字:

  1. 如果当前数字不小于栈顶,就入栈(分块的最大数字)
  2. 否则,当前数字要合并到栈顶数字的块里,栈内数字依次出栈,直到栈顶<=当前数字。再把原来的栈顶入栈。 最后返回栈长度。

    代码

    class Solution {
    public int maxChunksToSorted(int[] arr) {
        Deque<Integer> stack = new LinkedList<>();
        for (int num : arr) {
            if (stack.isEmpty() || stack.peek() <= num) {
                stack.push(num);
            } else {
                int top = stack.pop();
                while (!stack.isEmpty() && stack.peek() > num) {
                    stack.pop();
                }
    
                stack.push(top);
            }
        }
    
        return stack.size();
    }
    }

    TC: O(n) SC: O(n)

Toms-BigData commented 2 years ago

【Day 6】768. 最多能完成排序的块 II

思路

借鉴题解 单调栈:要想保证每一个块拼接后单调递增,就要保证每一个块的最大值是单调递增的,这时候就可以构建一个单调栈。 具体做法: 1.遍历数组arr中的每一个num 2.当stack为空或者num>=栈顶值时:入栈(相当于添加了新的元素块) 3.当栈 stack 不为空且数字 num<栈顶值 时: (1)保存栈顶值head *(2)当栈 stack 不为空且数字 num<栈顶值 时:循环出栈(此步是关键,因为num>=栈顶值时才能保证有序,所以要将前面所有的大于num的块儿合成一个) (3)将head入栈(当前块的最大值) 4.遍历结束后,stack的长度就是块的个数(很好理解,想一下就明白了)

Golang代码

func maxChunksToSorted(arr []int) int {
    if len(arr) == 0{
        return 0
    }
    stack := []int{}
    head := -1
    for i:=0;i<len(arr);i++{
        if len(stack) == 0 || arr[i] >= head{
            stack = append(stack,arr[i])
            head = arr[i]
        }else if arr[i]<head{
            for len(stack)!= 0 &&stack[len(stack)-1]>arr[i]{
                stack = stack[:len(stack)-1]
            }
            stack = append(stack,head)
        }
    }
    return len(stack)
}

复杂度

时间:O(n) 空间:O(n)

iambigchen commented 2 years ago

思路

用栈存下可以划块的最大值,如果下个值比栈顶的值要大,则直接入栈。如果小于栈顶的值,说明当前的值不能单独划块,需要和栈顶的值放到同一个块中。同时也需要继续遍历栈中的元素,因为只有前面分的块最大值要小于当前值,才能保证分块正确。不然该块应该也被划分到栈顶的块中

关键点

代码

JavaScript Code:


/**
 * @param {number[]} arr
 * @return {number}
 */
var maxChunksToSorted = function(arr) {
    let stack = []
    for (let i = 0; i < arr.length; i++) {
       let cur = arr[i]
       if (stack.length && stack[stack.length - 1] > cur) {
         let top = stack[stack.length - 1]
         while(stack.length && stack[stack.length - 1] > cur) {
            stack.pop()
         }
         stack.push(top)
       } else {
           stack.push(cur)
       }
    }
    return stack.length
};

复杂度分析

令 n 为数组长度。

yijing-wu commented 2 years ago

思路

代码


class Solution {
    public int maxChunksToSorted(int[] arr) {
        Stack<Integer> stack = new Stack<>();
        for(int i = 0; i < arr.length; i++) {
            if(stack.isEmpty() || arr[i] >= stack.peek()) {
                stack.push(arr[i]);
            } else {
                int head = stack.pop();
                while(!stack.isEmpty() && arr[i] < stack.peek() ) {
                    stack.pop();
                }
                stack.push(head);
            }
        }
        return stack.size();
    }
}

复杂度分析

hdyhdy commented 2 years ago
func maxChunksToSorted(arr []int) int {
    stack := []int{}
    for _,x := range arr{
        if len(stack)>0 && x < stack[len(stack)-1]{
            temp := stack[len(stack)-1]
            for len(stack)>0 && x < stack[len(stack)-1]{
            stack = stack[:len(stack)-1]
            }
            stack = append(stack,temp)
        }else{
            stack = append(stack,x)
        }
    }
    return len(stack)
}

复杂度为n

xiao-xiao-meng-xiang-jia commented 2 years ago

class Solution { public int maxChunksToSorted(int[] arr) { Map<Integer, Integer> count = new HashMap(); int ans = 0, nonzero = 0;

    int[] expect = arr.clone();
    Arrays.sort(expect);

    for (int i = 0; i < arr.length; ++i) {
        int x = arr[i], y = expect[i];

        count.put(x, count.getOrDefault(x, 0) + 1);
        if (count.get(x) == 0) nonzero--;
        if (count.get(x) == 1) nonzero++;

        count.put(y, count.getOrDefault(y, 0) - 1);
        if (count.get(y) == -1) nonzero++;
        if (count.get(y) == 0) nonzero--;

        if (nonzero == 0) ans++;
    }

    return ans;
}

} 时间复杂度: O(N \log N)O(NlogN) 空间复杂度: O(N)O(N)

ggohem commented 2 years ago

思路:

用一个单调不减辅助栈存储每个排序块的最大值。具体来说:

代码:

import java.util.LinkedList;

class Solution {
    public int maxChunksToSorted(int[] arr) {
        LinkedList<Integer> list = new LinkedList<>();
        for (int num : arr) {
            if (list.isEmpty() || num >= list.getLast()) {
                list.addLast(num);
            } else {
                int head = list.removeLast();
                while (!list.isEmpty() && num < list.getLast()) list.removeLast();
                // 上面的代码用了短路与,如果判断条件num < list.getLast()在前,当栈为空时会出现判断错误,所以一定需要先确保栈不空再进行栈顶元素的判断
                list.addLast(head);
            }
        }
        return list.size();
    }
}

tips:

对栈顶元素进行判断时,一定要先对栈空与否进行判断。

时空复杂度:

1149004121 commented 2 years ago

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

思路

设此块中最大的为head,如果后面的数都大于等于head,那么就是排序快;如果后面的数小于head,应该将其并入块。这种单调不减的性质,考虑用单调栈来实现。
遍历数组arr,如果当前的数大于等于栈顶的数,则入栈;如果小于栈顶的数,则应将其并入块,同时将栈顶元素弹出记为head,如果后续的栈顶元素依旧大于当前数,说明这些栈顶元素应该并入块,一直弹出,再将head压入。head用于表示排序快的最大数。

代码


    var maxChunksToSorted = function(arr) {
        let stack = [];
        let head = 0;
        for(let num of arr){
            if(stack.length > 0 && num < stack[stack.length - 1]){
                head = stack.pop();
                while(stack.length > 0 && num < stack[stack.length - 1]){
                    stack.pop();
                }
                stack.push(head);
            } else{
                stack.push(num);
            }
        }
        return stack.length;
    };

复杂度分析

Tesla-1i commented 2 years ago
class Solution:
    def maxChunksToSorted(self, arr: List[int]) -> int:
        stack = []
        for x in arr:
            if not stack or stack[-1] <= x:
                stack.append(x)
            elif stack[-1] > x:
                tmp = stack[-1]
                while stack and stack[-1] > x:
                    stack.pop()
                stack.append(tmp)
        return len(stack)
now915 commented 2 years ago

单调栈

var maxChunksToSorted = function(arr) {
  let stack = []
  for (let index = 0; index < arr.length; index++) {
    if (stack.length && arr[index] < stack[stack.length - 1]) {
      const cur = stack[stack.length - 1]
      while (stack.length && arr[index] < stack[stack.length - 1]) {
        stack.pop()
      }
      stack.push(cur)
    } else {
      stack.push(arr[index])
    }
  }
  return stack.length
};
xiaowenhe commented 2 years ago
class Solution:
    def maxChunksToSorted(self, arr: List[int]) -> int:

        stack = []
        for i in range(len(arr)):
            if stack and stack[-1] > arr[i]:
                cur_ = stack.pop()
                while stack and stack[-1] > arr[i]:
                    stack.pop()
                stack.append(cur_)
            else:
                stack.append(arr[i])

        return len(stack)
guoling0019 commented 2 years ago

JavaScript Code:


/**
 * @param {number[]} arr
 * @return {number}
 */
var maxChunksToSorted = function(arr) {
    let stack = [];
        for(let i=0;i<arr.length;i++){
            if(stack.length>0&&stack[stack.length-1]>arr[i]){
                const cur = stack[stack.length-1]
                while(stack&&stack[stack.length-1]>arr[i]) stack.pop()
                stack.push(cur)
            }else{
                stack.push(arr[i])
            }
        }
        return stack.length
};

复杂度分析

令 n 为数组长度。

phybrain commented 2 years ago

思路

单调栈

代码

class Solution:
    def findblock(self, L: list) -> int:

        stack = []
        for l in L:

            if stack and l<stack[-1]:

                s = stack[-1]
                while stack and l < stack[-1]:
                    stack.pop()
                stack.append(s)
            else:
                stack.append(l)
        return len(stack)

复杂度分析

pengfeichencpf commented 2 years ago

class Solution { public int maxChunksToSorted(int[] arr) { int n = arr.length; int[] maxOfLeft = new int[n]; int[] minOfRight = new int[n];

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

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

    int res = 0;
    for (int i = 0; i < n - 1; i++) {
        if (maxOfLeft[i] <= minOfRight[i + 1]) res++;
    }

    return res + 1;
}

}  

Serena9 commented 2 years ago

代码

class Solution(object):
    def maxChunksToSorted(self, arr):
        """
        :type arr: List[int]
        :rtype: int
        """
        stack = []
        for a in arr:
            if stack and a < stack[-1]:
                cur = stack[-1]
                while stack and a < stack[-1]:
                    stack.pop()
                stack.append(cur)
            else:
                stack.append(a)
        return len(stack)

复杂度分析

时间复杂度:O(N)

空间复杂度:O(N)

alongchong commented 2 years ago

代码

class Solution {
    public int maxChunksToSorted(int[] arr) {
        LinkedList<Integer> stack = new LinkedList<Integer>();
        for(int num : arr){
            if(!stack.isEmpty() && num < stack.getLast()) {
                int head = stack.removeLast();
                while(!stack.isEmpty() && num < stack.getLast()) stack.removeLast();
                stack.addLast(head);
            }
            else stack.addLast(num);
        } 
        return stack.size();

    }
}

复杂度分析 时间复杂度:$0(N)$ 空间复杂度:$0(N)$

lilililisa1998 commented 2 years ago

def maxChunksToSorted(arr): stack = [arr[0]] for num in arr[1:]:

    if num >= stack[-1]:  # 大于栈顶【栈中的最大值】
        stack.append(num)
    else:  # 小于栈顶
        cur_ma = stack.pop()  # 记录下栈顶
        while stack and num < stack[-1]:  # 移除栈中大于当前值num的所有元素
            stack.pop()
        stack.append(cur_ma)  # 栈顶复位

return len(stack)
junbuer commented 2 years ago

思路

代码

    class Solution(object):
        def maxChunksToSorted(self, arr):
            """
            :type arr: List[int]
            :rtype: int
            """
            count = collections.defaultdict(int) 
            bound = 0 
            ans = 0
            for x, y in zip(arr, sorted(arr)): 
                if count[x] == -1: 
                    bound -= 1 
                if count[x] == 0: 
                    bound += 1 
                count[x] += 1

                if count[y] == 1: 
                    bound -= 1 
                if count[y] == 0: 
                    bound += 1 
                count[y] -= 1

                if bound == 0: 
                    ans += 1
            return ans

复杂度分析

HZGwebgit commented 2 years ago

思路

找到数组左边最小值,然后依次对比,

代码

/**
 * @param {number[]} arr
 * @return {number}
 */
var maxChunksToSorted = function(arr) {
    const minWithIndex = new Map();
    for(let i = arr.length-1; i > -1; i--){
        if(i == arr.length-1){
            minWithIndex.set(i, arr[i]);
        }
        else{
            minWithIndex.set(i, Math.min(minWithIndex.get(i+1), arr[i]));
        }
    }
    let blocks = 1, max = 0;
    for(let i = 0; i < arr.length; i++){
        max = arr[max]>=arr[i]? max:i;
        if(arr[max] <= minWithIndex.get(i+1)){
            blocks++;
        }
    }
    return blocks;
};

复杂度

时间复杂度:o(n)

codingowl0101 commented 2 years ago

class Solution { public int maxChunksToSorted(int[] arr) { int n = arr.length; int[] forward = new int[n]; int[] backward = new int[n];

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

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

    int res = 0;
    for (int i = 0; i < n - 1; i++) {
        if (forward[i] <= backward[i + 1]) res++;
    }

    return res + 1;
}

}

Laurence-try commented 2 years ago
class Solution:
    def maxChunksToSorted(self, arr: List[int]) -> int:
        arr_sort = arr.copy()
        arr_sort.sort()
        count = 0
        for i in range (len(arr)):
            arr_sub = arr[:(i+1)]
            arr_sort_sub = arr_sort[:(i+1)]
            arr_sub.sort()
            arr_sort_sub.sort()
            if arr_sub == arr_sort_sub:
                count += 1
        return count

class Solution:
    def maxChunksToSorted(self, arr: List[int]) -> int:
        stack = []
        for a in arr:
            if stack and stack[-1] > a:
                cur = stack[-1]
                while stack and stack[-1] > a: 
                    stack.pop()
                stack.append(cur)
            else:
                stack.append(a)
        return len(stack)
xjhcassy commented 2 years ago

思路

  1. 采用滑动窗口

代码

class Solution {
    public int maxChunksToSorted(int[] arr) {
        int[] sortedArray = arr.clone();
        Arrays.sort(sortedArray);
        long arrSum = 0;
        long sortedSum = 0;
        int chunkCount = 0;
        for (int i = 0; i < arr.length; i++) {
            arrSum += arr[i];
            sortedSum += sortedArray[i];
            if(arrSum == sortedSum) chunkCount++;
        }
        return chunkCount;
    }
}

复杂度分析

时间复杂度:O(NlogN),N 为数组长度,数组排序时间认为是 NlogN,滑动窗口遍历数组时间为 N。;

空间复杂度:O(N);

stackvoid commented 2 years ago

思路

我们知道数组 arr 在排序之后一定跟整个数组排序后相应的地方完全相同,即 expect = sorted(arr)。如果前 k 个元素的个数减去排序后前 k 个元素的个数都为 0 的话,那这前 k 个元素是可以成为一个合法的分块的。对于整个数组可以重复这一过程。

用变量 nonzero 来计数目前差值不等于 0 的字符的个数。

class Solution {
    public int maxChunksToSorted(int[] arr) {
        Map<Integer, Integer> count = new HashMap();
        int ans = 0, nonzero = 0;

        int[] expect = arr.clone();
        Arrays.sort(expect);

        for (int i = 0; i < arr.length; ++i) {
            int x = arr[i], y = expect[i];

            count.put(x, count.getOrDefault(x, 0) + 1);
            if (count.get(x) == 0) nonzero--;
            if (count.get(x) == 1) nonzero++;

            count.put(y, count.getOrDefault(y, 0) - 1);
            if (count.get(y) == -1) nonzero++;
            if (count.get(y) == 0) nonzero--;

            if (nonzero == 0) ans++;
        }

        return ans;
    }
}

复杂度分析

时间复杂度: O(NlogN),其中 N 为 arr 的长度。 空间复杂度: O(N)。

Liuxy94 commented 2 years ago

思路

利用单调栈

代码

class Solution(object):
    def maxChunksToSorted(self, arr):
        """
        :type arr: List[int]
        :rtype: int
        """
        stack = [arr[0]]
        for num in arr[1:]:
            if stack[-1]<=num:
                stack.append(num)
            else:
                curr = stack[-1] #记录栈顶
                stack.pop()
                while stack and stack[-1]>num:
                    stack.pop()
                stack.append(curr) #复位

        return len(stack)

复杂度分析

空间 O(n)

时间 O(n)

L-SUI commented 2 years ago

var maxChunksToSorted = function (arr) { const sorted = [...arr]; sorted.sort((a, b) => a - b); let count = 0, sum1 = 0, sum2 = 0; for (let i = 0; i < arr.length; i++) { sum1 += arr[i]; sum2 += sorted[i]; if (sum1 === sum2) count++; } return count; };

Alyenor commented 2 years ago

思路

贪心 将整个数组 a 排序记作 b,a 的第一部分和b 的第一部分应该是一样的,a 的第二部分和b 的第二部分应该是一样的,依次类推。 从左往右遍历 a,当扫描到第一个位置 n,使得a[0,n] 和 b[0,n] 的元素是一致的,那么 [0,n] 就可以作为一个区间,依次类推。

代码 function maxChunksToSorted(arr: number[]): number { let res = 0; // 把原始数组 arr 进行排序 let b = [...arr].sort((a, b) => a - b); // 定义 map,key 是 arr 的每一个元素,值的初始值为 0 let m = new Map(); arr.forEach((x) => m.set(x, 0)); // m[arr[i]] 的值是否为零,也就是在这个区间里,arr[i] 同时在 arr 和 b 里 for (let i = 0, s = 0; i < arr.length; i++) { if (m.get(arr[i]) === 1) s -= 1; else if (m.get(arr[i]) === 0) s += 1; m.set(arr[i], m.get(arr[i]) - 1); if (m.get(b[i]) === -1) s -= 1; else if (m.get(b[i]) === 0) s += 1; m.set(b[i], m.get(b[i]) + 1); if (!s) res += 1; } return res; }

分析 时间复杂度 O(nlogn) 空间复杂度 O(n)

KevinWorkSpace commented 2 years ago
    public int maxChunksToSorted(int[] arr) {
        Stack<Integer> stack = new Stack<>();
        for (int i=0; i<arr.length; i++) {
            if (stack.isEmpty() || stack.peek() <= arr[i]) {
                stack.add(arr[i]);
            }
            else if (stack.peek() > arr[i]) {
                int top = stack.pop();
                while (!stack.isEmpty() && stack.peek() > arr[i]) stack.pop();
                stack.add(top);
            }
        }
        return stack.size();
    }
ZhangNN2018 commented 2 years ago

思路

复杂度

代码

class Solution(object):
    def maxChunksToSorted(self, arr):
        """
        :type arr: List[int]
        :rtype: int
        """
        res=1
        maxt=[0]*len(arr)
        maxt[0]=arr[0]
        mint=[0]*len(arr)
        mint[-1]=arr[-1]
        for i in reversed(range(len(arr)-1)):
            mint[i]=min(arr[i],mint[i+1])

        for i in range(1,len(arr)):
            maxt[i]=max(arr[i],maxt[i-1])

        for i in range(len(arr)-1):
            if maxt[i] <= mint[i+1]:
                res=res+1
        return res
luo-FrontEnd commented 2 years ago

JavaScript 思路: 最主要的思路是 当数组里某一项小于之前栈里面的任何一项时,pop,然后继续走

var maxChunksToSorted = function(arr) {
    let stack = [arr[0]];
    let max = arr[0];
    for(let i = 1; i < arr.length; i++) {
        if(arr[i] >= max) {
            max = arr[i];
            stack.push(arr[i]);
        } else {
            while(stack && arr[i] < stack[stack.length - 1]) {
                stack.pop();
            }
            stack.push(max);
        }
    }
    return stack.length;
};
kite-fly6618 commented 2 years ago

思路

将原数组排序,对比排序数组和原数组,如果两个数组的前i项和相等,说明可以作为一个块。

代码

var maxChunksToSorted = function (arr) {
    let count = 0;
    let sum1 = 0; // 存arr的前i项和
    let sum2 = 0;

    const arrSort = [...arr].sort((a, b) => a - b);

    for (let i = 0; i < arr.length; i++) {
        sum1 += arr[i];
        sum2 += arrSort[i];
        if (sum1 === sum2) {
            count++;
        }
    }

    return count;
}

复杂度

时间复杂度: O(NlogN)
空间复杂度: O(N)

15691894985 commented 2 years ago

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

https://leetcode-cn.com/problems/max-chunks-to-make-sorted-ii/

分割的临界点判断:

一直找到下一个比当前值小的元素 把分割区块考虑为融合区块,找到一个下一个比当前值小的就融合为一块,保留当前最大值到一个栈,然后将其入另外一个栈。栈里的每一个元素就是块的最大值。

class Solution {
    public int maxChunksToSorted(int[] arr) {
          LinkedList<Integer> stack = new LinkedList<Integer>();
          for (int num: arr){
              if (!stack.isEmpty() && num < stack.getLast()){
                  int cur = stack.removeLast();
                  while (!stack.isEmpty() && num < stack.getLast()){
                      stack.removeLast();
                  }
                  stack.addLast(cur);
              }else{
                  stack.addLast(num);
              }
          }
          return stack.size();
    }
}
niuyibo0619 commented 2 years ago

思路

代码

class Solution:
    def maxChunksToSorted(self, arr: List[int]) -> int:
        stack = []
        for i in arr:
            if len(stack)==0:
                stack.append(i)
            elif i >= stack[-1]:
                stack.append(i)
            elif i < stack[-1]:
                    head = stack.pop()
                    while len(stack) > 0:
                        if i < stack[-1]:
                            stack.pop()
                        else:
                            break
                    stack.append(head)
        return len(stack)

复杂度

zzzpppy commented 2 years ago

这个确实不会了,直接看的题解 class Solution { public int maxChunksToSorted(int[] arr) { LinkedList stack = new LinkedList(); for(int num : arr) { if(!stack.isEmpty() && num < stack.getLast()) { int head = stack.removeLast(); while(!stack.isEmpty() && num < stack.getLast()) stack.removeLast(); stack.addLast(head); } else stack.addLast(num); } return stack.size(); } }

MissNanLan commented 2 years ago

代码

JavaScript Code:


/**
 * @param {number[]} arr
 * @return {number}
 */
var maxChunksToSorted = function (arr) {
  let stack = [];
  for (var i = 0; i < arr.length; i++) {
    let head;
    // 合并
    if (stack.length > 0 && stack[stack.length - 1] > arr[i]) {
      head = stack.pop();
      while (stack.length > 0 && stack[stack.length - 1] > arr[i]) {
        stack.pop();
      }
      stack.push(head);
    } else {
      // 新的块
      stack.push(arr[i]);
    }
  }
  return stack.length;
};
machuangmr commented 2 years ago

代码

class Solution {
    public int maxChunksToSorted(int[] arr) {
         Stack<Integer> stack = new Stack<>();
        for (int num : arr) {
            if (!stack.isEmpty() && num < stack.peek()) {
                int current = stack.pop();
                while(!stack.isEmpty() && num < stack.peek()) {
                    stack.pop();
                }
                stack.push(current);
            } else {
                stack.push(num);
            }
        }
        return stack.size();
    }
}

复杂度

Myleswork commented 2 years ago

思路

单调栈

代码

class Solution {
public:
    int maxChunksToSorted(vector<int>& arr) {
        stack<int> stack;
        for(int i =0;i<arr.size();i++){
            if(!stack.empty()&&stack.top()>arr[i]){
                int cur = stack.top();
                while(!stack.empty()&&stack.top()>arr[i]){
                    stack.pop();
                }
                stack.push(cur);
            }else{
                stack.push(arr[i]);
            }
        }
        return stack.size();
    }
};

复杂度分析

时间复杂度:O(n)

空间复杂度:O(n)

Macvh commented 2 years ago

class Solution(object): def maxChunksToSorted(self, arr): """ :type arr: List[int] :rtype: int """ maximum, res = 0, 1 for i in range(len(arr)): maximum = max(arr[i], maximum) if i == len(arr) - 1: break elif min(arr[i+1:]) >= maximum: res += 1 return res

baddate commented 2 years ago

思路

根据题意可以推出:分块意味着左边块的最大值一定≤右边的最小值,顺着这个思路,只要找到左边最大值≤右边最小值的时候,就是一个块的分界线

代码

class Solution {
public:
    int maxChunksToSorted(vector<int>& arr) {
        int sz = arr.size();
        vector<int> lptr(sz, INT_MIN);
        vector<int> rptr(sz, INT_MAX);
        lptr[0] = arr[0];
        rptr[sz - 1] = arr[sz - 1];
        for (int i = 1; i < sz; ++i) {
            lptr[i] = max(lptr[i - 1], arr[i]);
            rptr[sz - 1 - i] = min(rptr[sz - i], arr[sz - 1 - i]);
        }
        int res = 1;
        for (int i = 0; i < sz - 1; ++i) {
            res += lptr[i] <= rptr[i + 1];
        }
        return res;
    }
};

复杂度分析

Today-fine commented 2 years ago

前块max <= 后块min


class Solution {
public:
    int maxChunksToSorted(vector<int>& arr) {
        stack<int>maxStk;
        maxStk.push(arr[0]);
        for(int i=1;i<arr.size();i++){
            if(arr[i]<maxStk.top()){
                int maxNum=maxStk.top();
                while(!maxStk.empty()&&maxStk.top()>arr[i])maxStk.pop();
                maxStk.push(maxNum);
            }
            else maxStk.push(arr[i]);
        }
        return maxStk.size();
    }
};
xj-yan commented 2 years ago
class Solution:
    def maxChunksToSorted(self, arr: List[int]) -> int:
        stack = []
        for num in arr:
            largest = num
            while stack and stack[-1] > num:
                largest = max(largest, stack.pop())
            stack.append(largest)
        return len(stack)

Time Complexity: O(n), Space Complexity: O(n)

mannnn6 commented 2 years ago

代码

class Solution {
    public int maxChunksToSorted(int[] arr) {
        Map<Integer, Integer> count = new HashMap();
        int ans = 0, nonzero = 0;

        int[] expect = arr.clone();
        Arrays.sort(expect);

        for (int i = 0; i < arr.length; ++i) {
            int x = arr[i], y = expect[i];

            count.put(x, count.getOrDefault(x, 0) + 1);
            if (count.get(x) == 0) nonzero--;
            if (count.get(x) == 1) nonzero++;

            count.put(y, count.getOrDefault(y, 0) - 1);
            if (count.get(y) == -1) nonzero++;
            if (count.get(y) == 0) nonzero--;

            if (nonzero == 0) ans++;
        }

        return ans;
    }
}

复杂度

时间复杂度:O(nlog(n))

空间复杂度:O(n)

kbfx1234 commented 2 years ago

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

// 12-17 求和-》计数
class Solution {
public:
    int maxChunksToSorted(vector<int>& arr) {
        vector<int> res = arr;
        sort(res.begin(),res.end());
        int ans = 0;
        long sum1 = 0, sum2 = 0;
        for (int i = 0; i < arr.size(); ++i) {
            sum1 += res[i];
            sum2 += arr[i];
            if (sum1 == sum2) ans++;
        }
        return ans;
    }
};
Neal0408 commented 2 years ago

这道题属实是不太会。。。

    def maxChunksTOSorted(self, arr: List[int]) -> int:
        stack = []
        for num in arr:
            if stack and num < stack[-1]:
                head = stack.pop()
                while stack and num < stack[-1]:
                    stack.pop()
                stack.append(head)
            else:
                stack.append(num)
        return len(stack)
LiFuQuan1208 commented 2 years ago

思路:

想了很久没有思路,群里大神说的滑动窗口之后明白了,困难的还是有难度啊

代码:

public int maxChunksToSorted(int[] arr) {
            int[] sortedArray = arr.clone();
            Arrays.sort(sortedArray);
            long arrSum = 0;
            long sortedSum = 0;
            int chunkCount = 0;
            for (int i = 0; i < arr.length; i++) {
                arrSum += arr[i];
                sortedSum += sortedArray[i];
                if(arrSum == sortedSum) chunkCount++;
            }
            return chunkCount;
    }

复杂度分析 -时间复杂度:O(N) -空间复杂度:O(N)

CodingProgrammer commented 2 years ago

思路

将数组与排序之后的标准数组做对比,如果当前数组遍历到的位置数字出现次数与标准数组一致,我们就可以将其看作一个块,将统计 map 都清空,继续统计

代码

class Solution {
    public int maxChunksToSorted(int[] arr) {
        // [1,1,0,0,1]
        // [0,0,1,1,1]
        int[] standard = arr.clone();
        Arrays.sort(standard);
        Map<Integer, Integer> mapStandard = new HashMap<>();
        Map<Integer, Integer> mapChunks = new HashMap<>();
        int res = 0;
        for (int i = 0; i < arr.length; i++) {
            mapChunks.put(arr[i], mapChunks.getOrDefault(arr[i], 0) + 1);
            mapStandard.put(standard[i], mapStandard.getOrDefault(standard[i], 0) + 1);
            if (mapStandard.equals(mapChunks)) {
                mapChunks.clear();
                mapStandard.clear();
                res++;
            }
        }
        return res;
    }
}

时间复杂度

dahaiyidi commented 2 years ago

From : https://github.com/dahaiyidi/awsome-leetcode

Problem

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

难度困难109

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

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

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


Note


Complexity


Python

class Solution:
    def maxChunksToSorted(self, arr: List[int]) -> int:
        st = [] 
        for num in arr:
            if st and st[-1] > num:
                head = st.pop()
                j = len(st) - 1
                while j >= 0 and st[j] > num:
                    st.pop()
                    j -= 1
                st.append(head)
            else:
                st.append(num)

        return len(st)

C++

class Solution {
public:
    int maxChunksToSorted(vector<int>& arr) {
        stack<int> st;
        for(auto num: arr){
            if(!st.empty() && st.top() > num){
                int head = st.top(); // 存储最后一个区域的最大值
                st.pop();
                while(!st.empty() && st.top() > num){
                    st.pop();  // 抛弃,直到遇到刚好st[j] <= num
                }
                st.push(head);
            }
            else{
                st.push(num);
            }
        }
        return st.size();
    }
};
noperoc commented 2 years ago

前置知识

思路

关键点

代码

Java Code:


class Solution {
    public int maxChunksToSorted(int[] arr) {
        LinkedList<Integer> stack = new LinkedList<Integer>();
        for(int num : arr) {
            if(!stack.isEmpty() && num < stack.getLast()) {
                int head = stack.removeLast();
                while(!stack.isEmpty() && num < stack.getLast()) stack.removeLast();
                stack.addLast(head);
            }
            else stack.addLast(num);
        }
        return stack.size();
    }
}

复杂度分析

令 n 为数组长度。