【刷题日记】769. 最多能完成排序的块

简介: 【刷题日记】769. 最多能完成排序的块

本次刷题日记的第 91 篇,力扣题为:769. 最多能完成排序的块

一、题目描述:

买股票的三连刷我们写完了,今天来刷 最多能完成排序的块

image.png

二、这道题考察了什么思想?你的思路是什么?

最多能排序的块,不知 xdm 看上去是否感觉和买股票有点相似,或者说和上一次的用户分组也非常相似,都是需要我们拆分数组,只不过题目要求和条件不一样罢了,那么我们的实现方式又有何不同呢,来看看

  • 题目给出一个长度为 n 的数组,数组中的元素是唯一的,且是 0 到 n-1 的序列,顺序是被打乱的
  • 这个时候,题目要求我们去拆分数组,尽可能的拆分成最多的块唯一要求就是,这些拆分的块排序后,按照顺序拼接起来,与源数组排序后(升序)的结果是一致的

分析

看了上面的描述和转义,其实我们对题目的要求还是相当明确的,可是我们需要去实现这个需求呢

第一,我们要把握住拆分最多的块

第二,我要需要注意原数组,和拆分后的块,是需要升序排序后对比的

第三,我们要清晰的知道数组中的数字是不会重复的,且一定是 0 到 n-1

也就是说,如果 n 等于 8 , 那么 0 到 7 这 8 个数字一定在数组中,只是顺序被打乱的了而已

我们可以来看看 0 到 7 如果排序后是什么样子的

索引 0 1 2 3 4 5 6 7
数值 0 1 2 3 4 5 6 7

其实通过上述表格我们清晰的可以看到,实际上数组的索引和数组的值是一一对应的,那么这个时候,如果 0 到 7 这个串数字是被打乱的话,我们可以如何来去拆分后,拼接成升序数组呢

举个栗子:

索引 0 1 2 3 4 5 6 7
数值 0 3 2 1 7 5 6 4

这个时候,通过这个小案例,其实,我们一眼就能看出需要如何拆分,例如这样

image.png

明确是拆分成 3 份的,当然,如果对于数据量大,那肯定就不能是一眼看出,必然是需要遵循某种逻辑和算法的

仔细看第 2 块,实际上我们就是在遍历数组的时候,如果当前索引 例如 1,不等于当前值例如 3,那么就需要记录下来当前的值 例如 maxNum = 3 ,遍历过程中,如果有更大的值但是和索引不相等的情况,那么就更新 maxNum,直到我们遍历到 索引与 maxNum 相等时候,那么这个时候就该拆分素组了,例如第 2 块,就是遍历到 索引为 3 ,maxNum 为 3 的时候,我们的程序就知道需要拆分数组了

当然第 3 块也是同样的道理

这个时候,剩下的就是开心的撸代码了,一次撸代码开心一次,一直撸代码,一直开心

三、编码

根据上述逻辑和分析,我们就可以翻译成如下代码

  • 我们需要重点关注区间内 maxNum 是否和当前索引相当,若相等,则拆分

编码如下:

func maxChunksToSorted(arr []int) int {
    var res int
    var maxNum int
    // 直接找到数组中的目前为止最大值,是否和目前索引对的上,若对的上就分区间
    for i:=0; i<len(arr); i++ {  
        maxNum = max(arr[i], maxNum)
        if i == maxNum {
            res++
         }
    }
    return res
}
func max(a, b int) int {
    if a>b {
        return a
    }
    return b
}

四、总结:

image.png

原题地址:769. 最多能完成排序的块

本题的实现方式,完成了一次遍历 arr 数组,因此时间复杂度是 O(n),空间复杂度为 O(1) ,咱们未印日额外的空间消耗

欢迎点赞,关注,收藏

朋友们,你的支持和鼓励,是我坚持分享,提高质量的动力

image.png

好了,本次就到这里

技术是开放的,我们的心态,更应是开放的。拥抱变化,向阳而生,努力向前行。

我是阿兵云原生,欢迎点赞关注收藏,下次见~

相关文章
LeetCode题解-让所有学生保持开心的分组方法数
LeetCode题解-让所有学生保持开心的分组方法数
|
存储 Cloud Native
【刷题日记】871. 最低加油次数
本次刷题日记的第 78 篇,力扣题为:871. 最低加油次数,困难
|
Cloud Native Go 索引
【刷题日记】768. 最多能完成排序的块 II
【刷题日记】768. 最多能完成排序的块 II
|
索引 Cloud Native
【刷题日记】954. 二倍数对数组
本次刷题日记的第 21 篇,力扣题为:954. 二倍数对数组 ,中等
|
测试技术 Cloud Native
【刷题日记】532. 数组中的 k-diff 数对
本次刷题日记的第 67 篇,力扣题为:532. 数组中的 k-diff 数对,中等
|
存储 Cloud Native
【刷题日记】128. 最长连续序列
本次刷题日记的第 56 篇,力扣题为:128. 最长连续序列,中等
|
搜索推荐 Cloud Native
【刷题日记】1403. 非递增顺序的最小子序列
【刷题日记】1403. 非递增顺序的最小子序列
|
Cloud Native
【刷题日记】73. 矩阵置零
【刷题日记】73. 矩阵置零
C/C++ leetcode刷题的各种小tips记录
C/C++ leetcode刷题的各种小tips记录
137 0
Leetcode-每日一题769. 最多能完成排序的块(贪心)
需要怎么分割序列才是个问题,题目其实给了提示因为序列里的数只能是[0, n-1]所以选择[l, r] 连续的序列中的数一定是 [l, r] 这段区间的数字,所以我们只需要遍历数组,去找这段区间内最大的数字,即边界值r,因为他才是决定边界的数字,每次我们到达了r这个位置就表示下一段区间。
66 0
Leetcode-每日一题769. 最多能完成排序的块(贪心)