最多能完成排序的块 II——Leetcode768

本文介绍了LeetCode 768问题的解决方案,首先提供了初始版本的代码,虽然能解决问题但耗时较长。接着,通过优化,实现了精简版的代码,显著减少了运行时间,但空间复杂度保持不变。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

初始版本(耗时很长)

//arr[int],有重复元素
//将数组分块,每块排序,再组合
//组合后的结果,和按照升序排序后的原数组相同

//有示例2可以看出,某一位置可以分块的前提是,从该位置分出去的块,该块内包含的元素,与arr数组整体排序之后,对应位置的元素相同也就是[2,1]对应了[1,2],所以可以分成一块

//整体思路:
//先对arr进行升序排序,得到新数组arr1;
//逐个判断该位置处能否分块(难点)
//记录分块位置n,n+1即分块数

//分块判断依据,实质就是从arr和arr1中取出一部分元素,判断其内容是否一致
//(1)确定起点begin和终点end,初始end=begin+1,即保证块内至少有1个元素
//(2)分别取出arr[begin,end]和arr1[begin,end]部分元素,组成新的数组L1和L2(注,此时L1是无序的,L2是有序的)
//(3)对L1进行排序,排序后判断是否与L2完全一致
//(4)若一致,则end后边即使可以分块的位置,令n=n+1;此时更新begin的值,令begin=end,相当于将已经分出去的块舍弃
//(5)若不一致,则令end=end+1,重复执行(1)
//(6)终止条件,当遍历完整个数组arr之后,返回n+1

//注:在判断L1和L2是否一致的操作上,使用排序的话会增加大量运行时间,故使用数组求和是否相等即sum1==sum2来判断更好
class Solution {
public:
    int maxChunksToSorted(vector<int>& arr) {
        int begin=0,n=0,end=1;
        double sum1=0,sum2=0;    //由于题中要求,int型会出现溢出问题
        int len=arr.size();
        int i;
        vector<int> arr1=arr;
        sort(arr1.begin(), arr1.end()); 
        while(end<=len)    //遍历数组的终止条件
        {
            cout<<"begin="<<begin<<" end="<<end<<" len="<<len<<endl;
            sum1=0;sum2=0;
            for(i=begin;i<end;i++)    //计算[begin,end)之间的元素的和
            {
                sum1=sum1+arr[i];
                sum2=sum2+arr1[i];
            }
            cout<<"sum1="<<sum1<<" "<<"sum2="<<sum2<<endl;
            if(sum1==sum2)
            {
                if(end!=len){n++;}
                begin=end;
                end=begin+1;
            }
            else
            {
                end++;
            }
             cout<<"n="<<n<<endl;
        }
        return n+1;
    }
};

精简后的版本(代码量少,时间提升,空间占用没变)

class Solution {
public:
    int maxChunksToSorted(vector<int>& arr) {
        int begin=0,n=0;
        double sum1=0,sum2=0;    //由于题中要求,int型会出现溢出问题
        int len=arr.size();
        int i;
        vector<int> arr1=arr;
        sort(arr1.begin(), arr1.end()); 
        
        while(begin<len)    //遍历数组的终止条件
        {  
            sum1=sum1+arr[begin];
            sum2=sum2+arr1[begin];
            if(sum1==sum2)
            {
                n++; 
                sum1=0;sum2=0;   
            }
            begin++;   
        }
        
        return n;
        
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值