首页 > 其他分享 >LeetCode/最多能完成排序的块

LeetCode/最多能完成排序的块

时间:2022-08-15 06:55:09浏览次数:43  
标签:arr int cnt 最多能 vector 排序 LeetCode size

1. 最多能完成排序的块I

给定一个长度为 n 的整数数组 arr ,它表示在 [0, n - 1] 范围内的整数的排列。
我们将 arr 分割成若干 块 (即分区),并对每个块单独排序。将它们连接起来后,使得连接的结果和按升序排序后的原数组相同。
返回数组能分成的最多块数量。

//从左往右遍历、融合不在位的元素
class Solution {
public:
    int maxChunksToSorted(vector<int>& arr) {
        int ans = arr.size(), max_ = 0;
        for (int i = 0; i < arr.size(); ++i) {
            max_ = max(max_, arr[i]);
            if (max_ != i) ans--;//不在位则融合
        }
        return ans;
    }
};

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

arr是一个可能包含重复元素的整数数组,元素为任意整数

2.1 单调栈
class Solution {
public:
    int maxChunksToSorted(vector<int>& arr) {
        stack<int> s;//单调栈,记录当前块最大元素,用于分组融合
        for (auto &num : arr) {
            if (s.empty() || num >= s.top()) //注意处理空栈
                s.push(num);//大于之前分组,则新增块
            else {//否则进行融合
                int mx = s.top();//融合前记录分组最大元素
                s.pop();
                while (!s.empty() && s.top() > num) //单调栈融合
                    s.pop();
                s.push(mx);//放回分组最大元素
            }
        }
        return s.size();//返回分组个数
    }
};
简化写法
class Solution {
public:
    int maxChunksToSorted(vector<int>& arr) {
        stack<int> s;
        s.push(INT_MIN);//作为栈底
        for(int x: arr){
            int y = max(x, s.top());
            while(s.top() > x) s.pop();
            s.push(y);
        }
        return s.size() - 1;
    }
};
2.2 哈希表
class Solution {
public:
    int maxChunksToSorted(vector<int>& arr) {
        unordered_map<int, int> cnt;//哈希表计数判断分块
        int res = 0;
        vector<int> sortedArr = arr;//新增排序辅助数组
        sort(sortedArr.begin(), sortedArr.end());
        for (int i = 0; i < sortedArr.size(); i++) {//从左往右遍历
            int x = arr[i], y = sortedArr[i];
            cnt[x]++;//对x正向计数
            if (cnt[x] == 0) 
                cnt.erase(x);
            cnt[y]--;//对y反向计数
            if (cnt[y] == 0) 
                cnt.erase(y);

            if (cnt.size() == 0)//计数消除说明前面排序后相同,新增一组
                res++;
        }
        return res;
    }
};
2.3 前缀和(未证明)
class Solution {
public:
    int maxChunksToSorted(vector<int>& arr) {
        int n = arr.size();
        auto sortArr = arr;
        sort(sortArr.begin(), sortArr.end());

        int ans = 0;
        // 前缀和相同,则表示可独立出一个块
        long long sum = 0, sortSum = 0;
        for (int i = 0; i < n; i++) {
            sum += arr[i];//计算未排序前缀和
            sortSum += sortArr[i];//计算排序前缀和

            ans += (sum == sortSum);//相等说明前面元素排序后相同,分组加一
        }

        return ans;
    }
};
2.4 记录右侧最小值和左侧最大值(接雨水)
class Solution {
public:
    int maxChunksToSorted(vector<int>& arr) {
        vector<int> rightmin(arr.size());
        int rmin = INT_MAX;
        for(int i=arr.size()-1;i>=0;i--){//记录右侧最小元素
            rightmin[i] = rmin;
            rmin = min(rmin,arr[i]);
        }
        int lmax = INT_MIN;
        int res = 0;
        for(int i=0;i<arr.size();i++){
            lmax = max(lmax,arr[i]);//记录当前最大值
            if(lmax<=rightmin[i]) res++;//左侧最大值小于右侧最小值,说明满足分组
        }
        return res;
}
};

标签:arr,int,cnt,最多能,vector,排序,LeetCode,size
From: https://www.cnblogs.com/929code/p/16586933.html

相关文章

  • 【Java】List排序方法(包括对象、Map等内部排序实现)
    前言日常开发中经常会对List集合做排序操作,JDK为我们提供了强大的排序方法,可以针对对象、Map、基本类型等进行正/倒排序操作。参考博客:JAVA列表排序方法sort和reversed......
  • 详解二分查找算法 && leetcode35. 搜索插入位置
    https://blog.csdn.net/weixin_39126199/article/details/118785065 https://leetcode.cn/problems/search-insert-position/classSolution{public:intsearc......
  • 数组根据时间戳排序
    exportfunctioncompare(arr,key,type="asc"){returnarr.sort((value1,value2)=>{constval1=value1[key];constval2=value2[key];//re......
  • leetcode3-无重复字符的最长子串
    无重复字符的最长子串滑动窗口需要记录左边界left。当右边界移动的时候,如果新加入的字符已经存在,那么需要更新左边界,让left取左边界和上一个字符位置的最大值。之后更......
  • leetcode1-两数之和
    两数之和暴力遍历classSolution{publicint[]twoSum(int[]nums,inttarget){intn=nums.length;for(inti=0;i<n;i++){......
  • leetcode2-两数相加
    两数相加循环,每次相加都new一个新的节点classSolution{publicListNodeaddTwoNumbers(ListNodel1,ListNodel2){ListNodehead=null,tail=nu......
  • leetcode(14)矩阵搜索系列题目
    64.最小路径和动态规划classSolution:defminPathSum(self,grid:List[List[int]])->int:m,n=len(grid),len(grid[0])res=0......
  • Java学习 (20) Java数组篇(04)Arrays类&冒泡排序&稀疏数组
    目录Arrays类语法实例冒泡排序语法实例具体讲解视频(狂神说Java)稀疏数组语法实例具体讲解视频(狂神说Java)Arrays类教组的工具类java.util.Arrays由于数组对象本身并没有......
  • [LeetCode] 2374. Node With Highest Edge Score
    Youaregivenadirectedgraphwith n nodeslabeledfrom 0 to n-1,whereeachnodehas exactlyone outgoingedge.Thegraphisrepresentedbyagiven......
  • leetcode438_找到字符串中所有字母异位词
    438.找到字符串中所有字母异位词方法一:简单滑动窗口满足异位词条件:(1)s中子串s'与目标字符串p的长度相等(2)s'与p中字母相同(对排列方式没有要求)算法思路:在字符串s中构......