(leetcode算法题)769. 最多能完成排序的块

Q1. 是否能用贪心算法?为什么?

先预设一个策略,每当当前的nums[i]满足可以 "成块",就直接让这个数成块,也就是说之后的遍历过程中不会将这个数在考虑到自己的块内,

"成块" 是指只要只需要将nums[i]放到前面的某个子数组的尾部,然后将这个子数组进行排序,就能得到一个拥有连续自然数的子数组,就称为成块

能够使用谈心算法是因为有如下规律

规律1. 以nums[i]为结尾的成块的子数组,其中的最大值不能小于 i

反证法:假设nums[i]为结尾的成块的子数组,其中最大值小于 i

那么对这个子数组进行排序后,最后一个值即为maxval,且其下标标定位i

子数组最开始的那个下标设为j, 那么子数组中应该有 i - j + 1个元素

又根据成块的定义,这里将会缺少自然数填满i - j + 1个位置矛盾

故,想要成块,子数组的最大值不能小于 i

下面以图示的方法进一步说明,假设红线前的0 1 2已经成块了

如果 nums[7] < 7 那么一定不能成块,因为此时只能有 6 5 4 3 2 1 0 能放入这8个黑框中,

规律2. 以nums[i]为结尾的成块的子数组,其中的最大值不能大于 i

证明与上面类似,矛盾之处在于如果最大值大于 i ,则将会多出来一个元素

所以要想成块只能是maxval == i

cpp 复制代码
class Solution {
public:
    int maxChunksToSorted(vector<int>& arr) {
        int n = arr.size();
        int ret = 0;
        int curmax = 0;
        for(int i = 0; i < n; ++i){
            curmax = max(curmax, arr[i]);
            if(curmax == i){
                ret++;
            }
        }
        return ret;
    }
};
相关推荐
代码游侠2 小时前
日历的各种C语言实现方法
c语言·开发语言·学习·算法
春日见6 小时前
丝滑快速拓展随机树 S-RRT(Smoothly RRT)算法核心原理与完整流程
人工智能·算法·机器学习·路径规划算法·s-rrt
Code小翊6 小时前
”回调“高级
算法·青少年编程
云里雾里!6 小时前
力扣 977. 有序数组的平方:双指针法的优雅解法
算法·leetcode·职场和发展
一只侯子9 小时前
Face AE Tuning
图像处理·笔记·学习·算法·计算机视觉
jianqiang.xue9 小时前
别把 Scratch 当 “动画玩具”!图形化编程是算法思维的最佳启蒙
人工智能·算法·青少年编程·机器人·少儿编程
不许哈哈哈9 小时前
Python数据结构
数据结构·算法·排序算法
J***793910 小时前
后端在分布式系统中的数据分片
算法·哈希算法
Dream it possible!11 小时前
LeetCode 面试经典 150_二叉搜索树_二叉搜索树中第 K 小的元素(86_230_C++_中等)
c++·leetcode·面试
sin_hielo12 小时前
leetcode 2872
数据结构·算法·leetcode