leetcode *1191. K 次串联后最大子数组之和(待研究)

【题目】*1191. K 次串联后最大子数组之和

53.最大子序和
*152. 乘积最大子数组
*1186. 删除一次得到子数组最大和
*1191. K 次串联后最大子数组之和

给你一个整数数组 arr 和一个整数 k。
首先,我们要对该数组进行修改,即把原数组 arr 重复 k 次。
举个例子,如果 arr = [1, 2] 且 k = 3,那么修改后的数组就是 [1, 2, 1, 2, 1, 2]。
然后,请你返回修改后的数组中的最大的子数组之和。
注意,子数组长度可以是 0,在这种情况下它的总和也是 0。
由于 结果可能会很大,所以需要 模(mod) 10^9 + 7 后再返回。

示例 1:

输入:arr = [1,2], k = 3
输出:9

示例 2:

输入:arr = [1,-2,1], k = 5
输出:2

示例 3:

输入:arr = [-1,-2], k = 7
输出:0

提示:
1 <= arr.length <= 10^5
1 <= k <= 10^5
-10^4 <= arr[i] <= 10^4

【解题思路1】

  • k = 1: max = 最大子串
  • k >= 1:
    如果数组和>0:max = 最大后子串 + (k - 2)*数组和 + 最大前子串
    如果数组和<=0:max = 最大后子串 + 最大前子串
  • 最后max与最大子串做对比,取最大值

会因为int类型溢出而解答错误

class Solution {
    public long MaxSub(int[] arr, int len){
        // 求最大子串
        long maxEndNow = 0;
        long maxSub = 0;
        for(int i = 0; i < len; i++) {
            maxEndNow = Math.max(maxEndNow + arr[i], 0);
            maxSub = Math.max( maxSub, maxEndNow);
        }
        return maxSub;
    }

    public int kConcatenationMaxSum(int[] arr, int k) {
        int i;
        long sum, res;
        long maxSub=0;
        long maxPre=0;
        long maxPost=0;  
        int len = arr.length;
        if(arr == null || len == 0) {
            return 0;
        }
        sum = 0;
        // 得到数组和
        for(i = 0; i < len; i++) {
            sum = sum + arr[i];
        }
        // 得到最大前子串
        sum = 0;
        for(i = 0; i < len; i++) {
            sum = sum + arr[i];
            maxPre = Math.max( maxPre, sum);
        }
        // 得到最大后子串
        sum = 0;
        for(i = len - 1; i >= 0; i--) {
            sum = sum + arr[i];
            maxPost = Math.max( maxPost, sum);
        }
        // 得到最大子串
        maxSub = MaxSub(arr, len);
        if(k == 1) {
            res =  maxSub;
        } else {
            if(sum > 0) {
                res =  maxPost + (k - 2) * sum +  maxPre;
            } else {
                res =  maxPost +  maxPre;
            }
            res = Math.max(res,  maxSub);
        }
        return (int)res % 1000000007;
    }
}

【解题思路2】动态规划 - Kadane算法(待研究)

class Solution {
    public int kConcatenationMaxSum(int[] arr, int k) {
        if (arr == null || arr.length == 0){
            return 0;
        }
        long maxOfEnd = arr[0] > 0 ? arr[0] : 0L;
        long maxSoFar = maxOfEnd;
        long sum = arr[0];
        for (int i = 1; i < Math.min(k, 2) * arr.length; i++) {
            maxOfEnd = Math.max(maxOfEnd + arr[i % arr.length], arr[i % arr.length]);
            maxSoFar = Math.max(maxOfEnd, maxSoFar);
            if (i < arr.length){
                sum += arr[i];
            }
        }
        while (sum > 0 && --k >= 2)
            maxSoFar = (maxSoFar + sum) % 1000000007;
        return (int) maxSoFar;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章