zoukankan      html  css  js  c++  java
  • 689. Maximum Sum of 3 Non-Overlapping Subarrays三个不重合数组的求和最大值

    [抄题]:

    In a given array nums of positive integers, find three non-overlapping subarrays with maximum sum.

    Each subarray will be of size k, and we want to maximize the sum of all 3*k entries.

    Return the result as a list of indices representing the starting position of each interval (0-indexed). If there are multiple answers, return the lexicographically smallest one.

    Example:

    Input: [1,2,1,2,6,7,5,1], 2
    Output: [0, 3, 5]
    Explanation: Subarrays [1, 2], [2, 6], [7, 5] correspond to the starting indices [0, 3, 5].
    We could have also taken [2, 1], but an answer of [1, 3, 5] would be lexicographically larger.

     [暴力解法]:

    时间分析:

    空间分析:

     [优化后]:

    时间分析:

    空间分析:

    [奇葩输出条件]:

    [奇葩corner case]:

    note中已经提示了length,就只需要考虑k k&length的关系就了

    把“前i项”初始化为“第i项”,方便直接做差

    for (int i = 1; i <= n; i++) {
                sums[i] = sums[i - 1] + nums[i - 1];
            }

    [思维问题]:

    不知道为什么要用DP:每次都保存之前一组的状态,然后一个个向前更新和比价。

    求一组固定为k长度的数组时可用。

    //总和=本组和+之前组的和=本组最后之和-本组第一之和+之前的(从j - k开始的)dp求和值
    int curSum = sums[j] - sums[j - k] + dp[i - 1][j - k];

    [英文数据结构或算法,为什么不用别的数据结构或算法]:

    dp数组里存储了结果,可以通过不断输入index来把结果取出来:

    int index = n;
            for (int i = 2; i >= 0; i--) {
                res[i] = pos[i + 1][index];
                System.out.println("index = " +index);
                System.out.println("res[i] = pos[i + 1][index] = " +res[i]);
                
                index = res[i];
                System.out.println("index = " +index);
                System.out.println("----------------");
               
            }

    [一句话思路]:

    按照第123组来操作,

     总和=本组和+之前所有组的和

    [输入量]:空: 正常情况:特大:特小:程序里处理到的特殊情况:异常情况(不合法不合理的输入):

    [画图]:

    [一刷]:

    1. 序列型dp所有的有关数组、有关二维数组都要增加1个单位,调用的时候也要+1,因为第一位拿来初始化了。不初始化就是默认为0

    [二刷]:

    1. 发现把第0位给去掉了 不知道为何:
    [1,2,1,2,6,7,5,1]
    2
    
    i = 1
    i - 1 = 0
    nums[i - 1] = 1
    sum[i - 1] = 0
    sum[i - 1] = 1
    ---------------
    i = 2
    i - 1 = 1
    nums[i - 1] = 2
    sum[i - 1] = 0
    sum[i - 1] = 2
    ---------------
    i = 3
    i - 1 = 2
    nums[i - 1] = 1
    sum[i - 1] = 0
    sum[i - 1] = 1
    ---------------
    i = 4
    i - 1 = 3
    nums[i - 1] = 2
    sum[i - 1] = 0
    sum[i - 1] = 2
    ---------------
    i = 5
    i - 1 = 4
    nums[i - 1] = 6
    sum[i - 1] = 0
    sum[i - 1] = 6
    ---------------
    i = 6
    i - 1 = 5
    nums[i - 1] = 7
    sum[i - 1] = 0
    sum[i - 1] = 7
    ---------------
    i = 7
    i - 1 = 6
    nums[i - 1] = 5
    sum[i - 1] = 0
    sum[i - 1] = 5
    ---------------
    i = 8
    i - 1 = 7
    nums[i - 1] = 1
    sum[i - 1] = 0
    sum[i - 1] = 1
    ---------------

    [三刷]:

    [四刷]:

    [五刷]:

      [五分钟肉眼debug的结果]:

    [总结]:

    dp是存储一组状态的,可以拿来调用

    [复杂度]:Time complexity: O(n) Space complexity: O(n)

    [算法思想:迭代/递归/分治/贪心]:

    [关键模板化代码]:

    [其他解法]:

    [Follow Up]:

    [LC给出的题目变变变]:

     [代码风格] :

     [是否头一次写此类driver funcion的代码] :

    class Solution {
        public int[] maxSumOfThreeSubarrays(int[] nums, int k) {
            //ini: res[3], pos[4][n + 1], dp[4][n + 1]
            int n = nums.length;
            int[] res = new int[3];
            int[] sum = new int[n + 1];
            int[][] pos = new int[4][n + 1];
            int[][] dp = new int[4][n + 1];
            
            //cc
            if (nums == null || nums.length < 3 * k) return res;
            
            //ini:sum
            for (int i = 1; i <= n; i++) {
                int j = i - 1;
                System.out.println("i = "+i);
                System.out.println("i - 1 = "+j);
                System.out.println("nums[i - 1] = "+nums[i - 1]);
                System.out.println("sum[i - 1] = "+sum[i - 1]);
                
                sum[i - 1] = sum[i - 1] + nums[i - 1];
                
                System.out.println("sum[i - 1] = "+sum[i - 1]);
                System.out.println("---------------");
            }
            
            for (int i = 1; i <= 3; i++) {
                for (int j = k * i; j <= n; j++) {
                    int curSum = sum[j] - sum[j - k] + dp[i - 1][j - k];
                    if (curSum > dp[i][j - 1]) {
                        dp[i][j] = curSum;
                        pos[i][j] = j - k;
                    }else {
                        dp[i][j] = dp[i][j - 1];
                        pos[i][j] = pos[i][j - 1];
                    }
                }
            }
            
            //retrieve the answer
            int index = n;
            for (int i = 2; i >= 0; i--) {
                //
                res[i] = pos[i + 1][index];
                index = res[i];
            }
            //return
            return res;
        }
    }
    View Code
  • 相关阅读:
    作业
    复习整理3
    复习整理2
    复习整理1
    书籍-os 相关
    书籍正则
    书籍
    SocketServer 简化编写网络服务器的步骤
    socket 粘包
    经典排序算法
  • 原文地址:https://www.cnblogs.com/immiao0319/p/9102541.html
Copyright © 2011-2022 走看看