LeetCode——将数组分割成和相等的子数组 C++

 题目描述:截图取自LeetCode

         从该题目描述中0 < i, i + 1 < j, j + 1 < k < n - 1可以看出该数组至少有七个元素。且符合条件的数组一定满足如下结构:

 

        上图中的sum1~sum4中间不仅仅包含一个元素,也可能是多个元素。

        当我们知道了数组结构之后,可以逐步分析了,其实如果不考虑程序效率的话完全可以按照题目描述进行暴力求解,但是这道题在LeetCode上面的题目难度为困难,所以这道题一定不单单是暴力求解这么简单,其中需要用到剪枝的操作来优化代码。

        本程序所用到的剪枝基本思想为从前往后先固定i的值,计算出sum1。然后确定j的值并计算sum2,如果sum2的值不等于sum1,则舍弃掉该j值(因为题目要求四个sum都相等才可以)。同理继续遍历确定k的值,直到找出结果。

        但是在提交代码的时候依旧遇到了大数组超时的情况。但是可以发现预设的大数组都是特殊数组(前后全是0)因为只有这种情况才可以在计算sum1和sum4时直接忽略掉而不影响最终结果,所以在代码中加入对这种情况的剪枝即可。

        完整代码如下:

bool splitArray(vector<int>& nums) {
        long long int num=0,all=0;
        bool isok=false;
        int in,on;
        for(int i=0;i<nums.size();i++){//忽略数组前的大量0值
            if(nums[i]!=0){
                in=i;
                isok=true;
                break;
            }
        }
        if(in==0)in=1;
        for(int i=nums.size()-1;i>=0;i--){//忽略数组后方的大量0值
            if(nums[i]!=0){
                on=i;
                break;
            }
        }
        if(nums.size()<100)on=nums.size();
        if(!isok)return true;
        for(int i=in;i<on;i++){
            if(i>=nums.size())break;
            num=0;
            for(int ii=0;ii<=i-1;ii++)num+=nums[ii];//sum1(0~i-1)
            all=num;
            for(int j=i+2;j<on;j++){
                if(j>=nums.size())break;
                num=0;
                for(int ii=i+1;ii<=j-1;ii++)num+=nums[ii];//sum2(i+1~j-1)
                if(all!=num)continue;
                for(int k=j+2;k<on;k++){
                    if(k>=nums.size()-1)break;
                    num=0;
                    for(int ii=j+1;ii<=k-1;ii++)num+=nums[ii];//sum3(j+1~k-1)
                    if(all!=num)continue;
                    num=0;
                    for(int ii=k+1;ii<=nums.size()-1;ii++)num+=nums[ii];//sum4(k+1~n-1)
                    if(all==num)return true;
                }
            }
        }
        return false;
    }

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
题目描述:给定一个非负整数数组nums和一个整数m,你需要将这个数组m个非空的连续数组。设计一个算法使得这m个数组中的最大和最小。 解题思路: 这是一个典型的二分搜索题目,可以使用二分查找来解决。 1. 首先确定二分的左右边界。左边界为数组中最大的值,右边界为数组中所有元素之和。 2. 在二分搜索的过程中,计算出分割数组的组数count,需要使用当前的中间值来进行判断。若当前的中间值不够分割m个数组,则说明mid值偏小,将左边界更新为mid+1;否则,说明mid值偏大,将右边界更新为mid。 3. 当左边界小于等于右边界时,循环终止,此时的左边界即为所求的结果。 具体步骤: 1. 遍历数组,找到数组中的最大值,并计算数组的总和。 2. 利用二分查找搜索左右边界,从左边界到右边界中间的值为mid。 3. 判断当前的mid值是否满足题目要求,若满足则更新右边界为mid-1; 4. 否则,更新左边界为mid+1。 5. 当左边界大于右边界时,循环终止,返回左边界即为所求的结果。 代码实现: ```python class Solution: def splitArray(self, nums: List[int], m: int) -> int: left = max(nums) right = sum(nums) while left <= right: mid = (left + right) // 2 count = 1 total = 0 for num in nums: total += num if total > mid: total = num count += 1 if count > m: left = mid + 1 else: right = mid - 1 return left ``` 时间复杂度分析:二分搜索的时间复杂度为O(logN),其中N为数组的总和,而遍历数组的时间复杂度为O(N),因此总的时间复杂度为O(NlogN)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值