每日一题:LC 连续数列

大家好,今天分享一道动态规划(Dynamic Programming)的题目,连续数列

给定一个整数数组,找出总和最大的连续数列,并返回总和。
示例:
输入: [-2,1,-3,4,-1,2,1,-5,4]
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。

这道题的调用:一个固定变量,两个可变变量,picked表示选过没有的状态,index表示当前的坐标.

process(int[] a,int index,boolean picked)

如果选过了,那么有几种选择
1.选当前的,继续走下一步
2.只选当前的,不继续走了,这时候返回,相当于子数组的选取停止

如果没选过,那么有几种选择
1.选当前的,走下一步
2.不选,走下一步
3.选当前的,但不继续往后看了

暴力法1

	public static int maxSubArray(int[] nums) {
        if(nums == null || nums.length < 1) return 0;
        if(nums.length == 1) return nums[0];
        return process(nums,0,false);
    }


    public static int process(int[] a,int index,boolean picked){
        if(index >= a.length) return Integer.MIN_VALUE;
        //c1++;
        if(index == a.length-1) {
            return Math.max(a[index],Integer.MIN_VALUE);
        }
        int p1 = -1,p2 = -1,p3 = -1;
        if(!picked){
            // 选
            p1 = a[index] + process(a,index+1,true);
            p2 = a[index];
            // 不选
            p3 = process(a,index+1,false);
        }else {
            p1 = a[index] + process(a,index+1,true);
            p2 = a[index];
        }
        return Math.max(Math.max(p1,p2),p3);
    }

dp的方法

因为有两个可比变量,而且第二个是一个boolean类型的,所以这里使用0代表false,1代表true,建立一个dp表,之后改。
对于无意义的值的选取,一开始笔者选的是-1,但是在[-2.-1]的例子中出错了,因为在比较时会有干扰,所以后面选择MIN_VALUE,消除了干扰

	public static int maxSubArray2(int[] nums) {
        if(nums == null || nums.length < 1) return 0;
        if(nums.length == 1) return nums[0];
        int[][] dp = new int[nums.length][2];
        for (int i = 0; i < dp.length; i++) {
            dp[i][0] = Integer.MIN_VALUE;
            dp[i][1] = Integer.MIN_VALUE;
        }
        // [][0] not picked
        // [][1] have picked
        dp[nums.length-1][0] = nums[nums.length-1];
        dp[nums.length-1][1] = nums[nums.length-1];
        return process(nums,0,0,dp);
    }


    // picked < 0  --> not have picked
    // picked > 0  --> have picked
    public static int process(int[] a,int index,int picked,int[][] dp){
        if(index >= a.length) return Integer.MIN_VALUE;
        if(dp[index][picked] != Integer.MIN_VALUE) return dp[index][picked];
        //c2++;
        int p1 = Integer.MIN_VALUE,p2 = Integer.MIN_VALUE,p3 = Integer.MIN_VALUE;
        if(picked == 0){
            // 选
            p1 = a[index] + process(a,index+1,1,dp);
            p2 = a[index];
            // 不选
            p3 = process(a,index+1,0,dp);
            dp[index][picked] = Math.max(Math.max(p1,p2),p3);
        }else {
            p1 = a[index] + process(a,index+1,1,dp);
            p2 = a[index];
            dp[index][picked] = Math.max(p1,p2);
        }
        return dp[index][picked];
    }

欢迎点赞,评论,我们下期再见:)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值