算法入门1--分而治之

        新手入门的最大子序列和问题,就是一道典型的分治思想算法问题。这里引用浙江大学陈越老师的讲义内容:

         分而治之的思想就是将问题一分为二(我觉得其实也就是递归),再在子问题继续分,也就是递归。在这道题中,分完后就是“治”:每两个元素对比取max。不过这里我们需要考虑跨界问题,如上图左边,4-5间元素最大和为6,后续的分析都是一样的。

        以下是代码实现,它的时间复杂度是O(NlogN):

     public static int maxSum3(int[] nums,int left,int right){
         int mid=0,maxLeftSum=0,maxRightSum=0;
         int maxLeftBorderSum=0,maxRightBorderSum=0;
/当只有一个元素时
         if(left==right){
             return Math.max(nums[left], 0);
         }
         //分
         mid=(left+right)/2;
         maxLeftSum=maxSum3(nums,left,mid);
         maxRightSum=maxSum3(nums,mid+1,right);
         //跨界扫描
//向左扫描
         int leftBorderSum=0;
         for(int i=mid;i>=left;i--){
             leftBorderSum+=nums[i];
         }
         if(leftBorderSum>maxLeftBorderSum){
             maxLeftBorderSum=leftBorderSum;
         }
//向右扫描
         int rightBorderSum=0;
         for(int i=mid+1;i<=right;i++){
             rightBorderSum+=nums[i];
         }
         if(rightBorderSum>maxRightBorderSum){
             maxRightBorderSum=rightBorderSum;
         }

         return Math.max(maxLeftSum,Math.max(maxRightSum,maxLeftBorderSum+maxRightBorderSum));
     }

        这道题陈老师也提供了个更快的解法,代码实现就是:

    public static int maxSum4(int [] nums){
        int sum=0,maxsum=0;
        for(int i=0;i<nums.length;i++){
            sum+=nums[i];
            if(sum>maxsum){
                maxsum=sum;
//如果发现当前子序列和为负,抛弃
            }else if(sum<0){
                sum=0;
            }
        }
        return maxsum;
    }

        这个解法也比较好理解,它的时间复杂度是O(N)

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值