返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C++如何实现可排序的最大块数
  • 444
分享到

C++如何实现可排序的最大块数

2023-06-19 12:06:04 444人浏览 安东尼
摘要

今天小编给大家分享一下c++如何实现可排序的最大块数的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。Max Chunks To

今天小编给大家分享一下c++如何实现可排序的最大块数的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。

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

这道题是之前那道 Max Chunks To Make Sorted 的拓展,那道题说了数组是[0, n-1]中所有数字的一种全排列,n为数组的长度。而这道题的数字就没有这种限制,可以是大于n的数字,也可以有重复的数字。由于数字和坐标不再有太多的关联,所以之前那题中比较数字和坐标的大小的解法肯定行不通了。我们来看一种十分巧妙的解法,首先我们需要明确的一点是,拆分后的块儿排序后拼在一起会跟原数组相同,我们用一个例子来说明:

2  1  4  3  4

1  2  3  4  4

1  2  3  4  4

我们看到第一行是原数组,第二行是排序后并拼接在了一起的块儿,不同的颜色代表不同的块儿,而第三行是直接对原数组排序后的结果。仔细观察可以发现,能形成块儿的数字之和跟排序后的数组的相同长度的子数组的数字之和是相同的。比如第一个块儿是数字2和1,和为3,而排序后的前两个数字为1和2,和也是3,那么我们就知道原数组的前两个数字可以拆成一个块儿。同理,原数组中的第三个和第四个数字分别为4和3,和为7,而排序后的数组对应位置的数字之和也是7,说明可以拆分出块儿。需要注意的是,在累加数组和的时候有可能会超过整型最大值,所以我们用长整型来保存就可以了。就是这么简单而暴力的思路,时间复杂度为O(nlgn),主要花在给数组排序上了。由于本题是 Max Chunks To Make Sorted 的generalized的情况,所以这种解法自然也可以解决之前那道题了,不过就是时间复杂度稍高了一些,参见代码如下:

解法一:

class Solution {public:    int maxChunksToSorted(vector<int>& arr) {        long res = 0, sum1 = 0, sum2 = 0;        vector<int> expect = arr;        sort(expect.begin(), expect.end());        for (int i = 0; i < arr.size(); ++i) {            sum1 += arr[i];            sum2 += expect[i];            if (sum1 == sum2) ++res;        }        return res;    }};

这道题的时间复杂度可以优化到线性,不过就是需要花点空间。下面这种解法也相当的巧妙,我们需要两个数组forward和backward,其中 foward[i] 表示 [0, i] 范围内最大的数字,而 backward[i] 表示 [i, n-1] 范围内最小的数字,实际上就是要知道已经遍历过的最大值,和还未遍历的到的最小值。为啥我们对这两个值感兴趣呢?这是本解法的精髓所在,我们知道可以拆分为块儿的前提是之后的数字不能比当前块儿中的任何数字小,不然那个较小的数字就无法排到前面。就像例子1,为啥不能拆出新块儿,就因为最小的数字在末尾。那么这里我们能拆出新块儿的条件就是,当前位置出现过的最大值小于等于之后还未遍历到的最小值时,就能拆出新块儿。比如例子2中,当 i=1 时,此时出现过的最大数字为2,未遍历到的数字中最小值为3,所以可以拆出新块儿,参见代码如下:

解法二:

class Solution {public:    int maxChunksToSorted(vector<int>& arr) {        int res = 1, n = arr.size();        vector<int> f = arr, b = arr;           for (int i = 1; i < n; ++i) f[i] = max(arr[i], f[i - 1]);           for (int i = n - 2; i >= 0; --i) b[i] = min(arr[i], b[i + 1]);        for (int i = 0; i < n - 1; ++i) {            if (f[i] <= b[i + 1]) ++res;        }        return res;    }};

我们可以优化一下空间复杂度,因为我们可以在遍历的过程中维护一个当前最大值curMax,所以就不用一个专门的forward数组了,但是backward数组还是要的,参见代码如下: 

解法三:

class Solution {public:    int maxChunksToSorted(vector<int>& arr) {        int res = 1, n = arr.size(), curMax = INT_MIN;        vector<int> b = arr;            for (int i = n - 2; i >= 0; --i) b[i] = min(arr[i], b[i + 1]);        for (int i = 0; i < n - 1; ++i) {            curMax = max(curMax, arr[i]);            if (curMax <= b[i + 1]) ++res;        }        return res;    }};

下面这种使用单调栈Monotonous Stack的解法的题也十分的巧妙,我们维护一个单调递增的栈,遇到大于等于栈顶元素的数字就压入栈,当遇到小于栈顶元素的数字后,处理的方法很是巧妙啊:首先取出栈顶元素,这个是当前最大值,因为我们维护的就是单调递增栈啊,然后我们再进行循环,如果栈不为空,且新的栈顶元素大于当前数字,则移除栈顶元素。这步简直绝了,这里我们单调栈的元素个数实际上是遍历到当前数字之前可以拆分成的块儿的个数,我们遇到一个大于栈顶的元素,就将其压入栈,suppose其是一个新块儿的开头,但是一旦后面遇到小的数字了,我们就要反过来检查前面的数字,有可能我们之前认为的可以拆分成块儿的地方,现在就不能拆了,举个栗子来说吧:

比如数组为 [1 0 3 3 2],我们先把第一个数字1压入栈,此时栈为:

stack:1

然后遍历到第二个数字0,发现小于栈顶元素,将栈顶元素1取出存入curMax,此时栈为空了,不做任何操作,将curMax压回栈,此时栈为:

stack:1

然后遍历到第三个数字3,大于栈顶元素,压入栈,此时栈为:

stack:1,3

然后遍历到第四个数字3,等于栈顶元素,压入栈,此时栈为:

stack:1,3,3

然后遍历到第五个数字2,小于栈顶元素,将栈顶元素3取出存入curMax,此时新的栈顶元素3,大于当前数字2,移除此栈顶元素3,然后新的栈顶元素1,小于当前数字2,循环结束,将curMax压回栈,此时栈为:

stack:1,3

所以最终能拆为两个块儿,即stack中数字的个数,参见代码如下:

解法四:

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

以上就是“C++如何实现可排序的最大块数”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注编程网其他教程频道。

--结束END--

本文标题: C++如何实现可排序的最大块数

本文链接: https://lsjlt.com/news/296213.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • C++如何实现可排序的最大块数
    今天小编给大家分享一下C++如何实现可排序的最大块数的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。Max Chunks To...
    99+
    2023-06-19
  • C++实现LeetCode(769.可排序的最大块数)
    [LeetCode] 769.Max Chunks To Make Sorted 可排序的最大块数 Given an array arr that is a pe...
    99+
    2024-04-02
  • C++怎么实现可排序的最大块数
    这篇文章主要介绍“C++怎么实现可排序的最大块数”,在日常操作中,相信很多人在C++怎么实现可排序的最大块数问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C++怎么实现可排序的最大块数”的疑惑有所帮助!接下来...
    99+
    2023-06-20
  • C++实现可排序最大块数的方法
    这篇“C++实现可排序最大块数的方法”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“C++实现可排序最大块数的方法”文章吧。M...
    99+
    2023-06-19
  • C++实现可排序的最大块数的方法
    这篇文章主要介绍“C++实现可排序的最大块数的方法”,在日常操作中,相信很多人在C++实现可排序的最大块数的方法问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C++实现可排序的最大块数的方法”的疑惑有所帮助!...
    99+
    2023-06-20
  • C++实现LeetCode(768.可排序的最大块数之二)
    [LeetCode] 768.Max Chunks To Make Sorted II 可排序的最大块数之二 This question is the same as "Max Ch...
    99+
    2024-04-02
  • SQL如何实现组内排序取最大值
    这篇文章主要介绍了SQL如何实现组内排序取最大值,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。 测试用例--建表 create ...
    99+
    2024-04-02
  • C++如何实现序列排序
    这篇文章主要讲解了“C++如何实现序列排序”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C++如何实现序列排序”吧!Permutation Sequence 序列排序The set ...
    99+
    2023-06-19
  • C++如何实现堆排序
    这篇文章主要介绍“C++如何实现堆排序”,在日常操作中,相信很多人在C++如何实现堆排序问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C++如何实现堆排序”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!概述...
    99+
    2023-06-22
  • C#如何实现希尔排序
    本篇内容主要讲解“C#如何实现希尔排序”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C#如何实现希尔排序”吧!对于大规模乱序的数组,插入排序很慢,因为它只会交换相邻的元素,因此元素只能一点一点地...
    99+
    2023-06-30
  • C#如何实现归并排序
    这篇文章主要介绍“C#如何实现归并排序”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“C#如何实现归并排序”文章能帮助大家解决问题。什么是归并?即将两个有序的数组归并成一个更大的有序数组。什么是归并排...
    99+
    2023-06-30
  • python如何实现可排序词典
    这篇文章给大家分享的是有关python如何实现可排序词典的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。可排序词典>>> m = d...
    99+
    2024-04-02
  • C++如何实现最大矩形
    这篇文章主要讲解了“C++如何实现最大矩形”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C++如何实现最大矩形”吧!最大矩形Example:Input:[["1",&qu...
    99+
    2023-06-19
  • 如何实现计数排序
    这篇文章主要介绍“如何实现计数排序”,在日常操作中,相信很多人在如何实现计数排序问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”如何实现计数排序”的疑惑有所帮助!接下来,请跟着...
    99+
    2024-04-02
  • C语言如何实现数组元素排序
    这篇文章主要讲解了“C语言如何实现数组元素排序”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C语言如何实现数组元素排序”吧!前言在实际开发中,有很多场景需要我们将数组元素按照从大到小(或者从...
    99+
    2023-07-05
  • C++中如何实现冒泡排序
    这篇文章给大家介绍C++中如何实现冒泡排序,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。C++冒泡排序代码示例:#include < iostream.h> #include&...
    99+
    2023-06-17
  • C# SortedList排序列表如何实现
    这篇文章主要讲解了“C# SortedList排序列表如何实现”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C# SortedList排序列表如何实现”吧!在 C# 中,...
    99+
    2023-07-05
  • JavaScript如何实现十大排序算法
    本文小编为大家详细介绍“JavaScript如何实现十大排序算法”,内容详细,步骤清晰,细节处理妥当,希望这篇“JavaScript如何实现十大排序算法”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,...
    99+
    2024-04-02
  • Java C++题解leetcode769最多能完成排序的块
    目录题目要求思路:模拟JavaC++Rust总结题目要求 思路:模拟 Java class Solution { public int maxChunksToSorted...
    99+
    2022-11-13
    Java C++最多能完成排序的块 LeetCode最多能完成排序的块
  • C/C++qsort函数的实现(冒泡排序)
     个人主页: 仍有未知等待探索_数据结构,小项目,C语言疑难-CSDN博客 专题分栏: C语言疑难_仍有未知等待探索的博客-CSDN博客 目录 一、引言 二、讲解实现 1、给整型数组排序   排序实现 总代码  2、qsort...
    99+
    2023-10-20
    c语言 c++ 算法
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作