leetcode刷题:53-最大子序和(思路理解)

题型:动态规划

方法1:暴力查找


循环遍历即可

class Solution {
    public int maxSubArray(int[] nums) {
        int max=Integer.MIN_VALUE,sum=0;
    for(int i=0;i<nums.length;i++){
        sum=0;
        for(int j=i;j<nums.length;j++){
             sum+=nums[j];
             if(sum>max){
                 max=sum;
             }
        }
    }
  return max;
    }
}

方法2:动态规划


设nums有n个数,f(i)为nums某一段连续子数组之和,如果f (i)的下一个nums比f (i)加上该nums大,那么该f (i)加上该nums肯定不是最大子序和,因此将pre从该nums重新指定并往后累加,比较f (i)数组中相对较大值来求出最大值

(官方参考代码理解)

class Solution{
 public int maxsubarray(int[] nums)
 {
    int pre=0,max=-Integer.MAX_VALUE;
    for(int i=0;i<nums.length;i++)
    {
         pre=Math.max(pre+nums[i],nums[i]);//将当前f(i)和下一个nums比较
         max=Math.max(max,pre);//比较当前f(i)和上一个f(i-1)值
      }
      return max;
  }       

方法3:分治法


简单来说就是把数组不停对半分,类似二分法,只到不能再分为止。在每次对半分的同时,先求出左边的从最右边开始的最大子序和,记为lmax,在求出右边的从左边开始的最大子序和,记为rmax。由于左右两边是连续的,故可以求出总体子序值cmax=lmax+rmax;根据递归,当分到不能再分的时候,返回一个nums[start]到lsummax和rsummax;再返回到有四个数据的子集合,比较三者大小求出子序最大值;再返回到有八个数据的子集合,再求出最大值…以此类推。等同与法2中的求出一个f (i),然后比较f (i)数组中相对较大值求出最大值。

(非官方递归方法)

public Solution{

	public int maxarray(int[] nums)
		{
		   return maxdevide(int[] nums,0,nums.length-1);//返回要遍历的函数
		   }

	public maxdevide(int[] nums,int start,int end)
		   {
		    if(start==end){
		    return nums[start];//当递归到不能分时返回,递归结束
		    }
		    int center=(start+end)>>1;
		    int lmax=Iteger.MIN_VALUE,rmax=Iteger.MIN_VALUE;
		    int lsummax=0,rsummax=0;
		    lsummax=maxdevide(nums,start,center);//进行递归直到只有一个数,返回到lsummax,右同理
		    rsummax=maxdevide(nums,center+1,end);
		    for(int i=center;i>=start;;i--)//求出左边最大子连续和
		    {
		        int l=0;
		       lmax=Math.max(l+nums[i],lmax);//必须包含左侧最右边一个子序列最大值,右同理
		       }
		       for(int i=center+1;i<=end;i++)//求出右边最大子连续和
		       {
		          int r=0;
		          rmax=Math.max(r+nums[i],rmax);
		          }

		int dcross=lmax+rmax;//左右最大值相加值,连接左右区域
		return Math.max(dcross,Math.max(lsummax,rsummax));//由小到大返回该子集和最大值
		}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值