当前位置: 首页 > article >正文

算法随笔_38: 最多能完成排序的块

上一篇:算法随笔_37: 交替合并字符串-CSDN博客

=====

题目描述如下:

给定一个长度为 n 的整数数组 arr ,它表示在 [0, n - 1] 范围内的整数的排列。

我们将 arr 分割成若干  (即分区),并对每个块单独排序。将它们连接起来后,使得连接的结果和按升序排序后的原数组相同。

返回数组能分成的最多块数量。

示例 1:

输入: arr = [4,3,2,1,0]
输出: 1
解释:
将数组分成2块或者更多块,都无法得到所需的结果。
例如,分成 [4, 3], [2, 1, 0] 的结果是 [3, 4, 0, 1, 2],这不是有序的数组。

示例 2:

输入: arr = [1,0,2,3,4]
输出: 4
解释:
我们可以把它分成两块,例如 [1, 0], [2, 3, 4]。
然而,分成 [1, 0], [2], [3], [4] 可以得到最多的块数。
对每个块单独排序后,结果为 [0, 1], [2], [3], [4]

=====

算法思路:

让我们从右往左来分析这道题。

1.  倒数第一个数arr[-1],它自己为一个区间。我们暂时把它放入一个res的数组中。如果题目就一个元素,那最后答案肯定就为1。此时res=[arr[-1]]

2.  倒数第二个数arr[-2],如果它小于res[-1](即arr[-1]),最多的区间数就是2。并存入res。此时res=[arr[-1], arr[-2]]。依次类推,如果原数组中从后往前的序列是递减的趋势,那么区间数就是元素数,每个元素各自占一个区间。

3.  我们继续来看,当递减趋势的第一次升高时,比如在arr[-6]处,它大于arr[-5],即res[-1]。那它必然要和arr[-5]处在同一个区间,才能符合题目要求。

而且我们还注意到,如果arr[-6]也大于arr[-4],那arr[-6],arr[-5],arr[-4]这三个数都要处在同一个区间。换句话说,如果前一个区间最大的数,大于后一个区间最小的数,这两个区间必须合并为同一个区间。

因此,对于这种情况,我们需要做如下的处理:

a.  arr[-6]需要从后往前与res里的元素逐个比较,对于小于它的数,从res里删除。直到碰到比它大的数为止。

b. 对于已经删除的数中最小的那个值,需要保留。比如arr[-6]大于arr[-5],arr[-4],arr[-3],但是小于arr[-2]。需要保留arr[-5]。

c.  arr[-6]也无需存入res。

因此最终的res=[arr[-1], arr[-2], arr[-5]]。arr[-5]就是它所在区间最小的那个数。

到目前为止的分析,我们能从中发现一点规律了。我们发现res是一个递减序列。它的每个元素就是它所在区间的最小值。由于我们是从右往左遍历原数组,所以res数组总体是符合题目要求的,即,把res颠倒过来,再对每个区间排序,就可得到题目要求的样子。因此最终答案的区间总数就是res的长度。

当我们继续枚举原数组时,如果当前元素大于res[-1],我们按照步骤3做处理。如果小于res[-1],我们按照步骤2做处理。

下面是代码实现:

class Solution(object):
    def maxChunksToSorted(self, arr):
        """
        :type arr: List[int]
        :rtype: int
        """
        arr_len=len(arr)
        res=[arr[-1]]
        for i in range(arr_len-2,-1,-1):
            num_min=res[-1]
            while arr[i] > res[-1]:
                if len(res)>1 and arr[i]>res[-2]:
                    res.pop()
                else:
                    res[-1]=num_min
                    break
            if arr[i] < res[-1]:
                res.append(arr[i])
        return len(res)


http://www.kler.cn/a/532081.html

相关文章:

  • C语言第六课:数组与字符串
  • 实战:如何快速让新网站被百度收录?
  • opencv图像处理框架
  • 700. 二叉搜索树中的搜索
  • Vue 3 30天精进之旅:Day 13 - 路由守卫
  • 【memgpt】letta 课程1/2:从头实现一个自我编辑、记忆和多步骤推理的代理
  • 蓝桥杯真题 - 子串简写 - 题解
  • 开源 CSS 框架 Tailwind CSS
  • upload-labs安装与配置
  • SQL Server中DENSE_RANK()函数:简洁处理连续排名
  • 数据结构:树和二叉树概念_堆篇
  • apikey存储方案探秘(deepseek-R1对话)
  • 九. Redis 持久化-RDB(详细讲解说明,一个配置一个说明分析,步步讲解到位)
  • RabbitMQ深度探索:死信队列
  • PHP开发小记-消息推送
  • 《深度揭秘LDA:开启人工智能降维与分类优化的大门》
  • Android学习21 -- launcher
  • 设计一个特殊token以从1亿词表中动态采样8192个词来表达当前序列
  • CSS工程化概述
  • MFC程序设计(八)动态创建机制
  • mysql不同种类时间字段的区别
  • Linux ifstat 命令使用详解
  • qt-Quick笔记之Dark Mode And Light Mode In Application
  • 应对现代电子商务的网络威胁—全面安全战略
  • (脚本学习)BUU18 [CISCN2019 华北赛区 Day2 Web1]Hack World1
  • 自制小动画