• Leetcode 918. Maximum Sum Circular Subarray (单调队列好题)


    1. Maximum Sum Circular Subarray
      Medium

    Given a circular integer array nums of length n, return the maximum possible sum of a non-empty subarray of nums.

    A circular array means the end of the array connects to the beginning of the array. Formally, the next element of nums[i] is nums[(i + 1) % n] and the previous element of nums[i] is nums[(i - 1 + n) % n].

    A subarray may only include each element of the fixed buffer nums at most once. Formally, for a subarray nums[i], nums[i + 1], …, nums[j], there does not exist i <= k1, k2 <= j with k1 % n == k2 % n.

    Example 1:

    Input: nums = [1,-2,3,-2]
    Output: 3
    Explanation: Subarray [3] has maximum sum 3.
    Example 2:

    Input: nums = [5,-3,5]
    Output: 10
    Explanation: Subarray [5,5] has maximum sum 5 + 5 = 10.
    Example 3:

    Input: nums = [-3,-2,-3]
    Output: -2
    Explanation: Subarray [-2] has maximum sum -2.

    Constraints:

    n == nums.length
    1 <= n <= 3 * 104
    -3 * 104 <= nums[i] <= 3 * 104

    解法1:
    不用滑动窗口和单调队列。实际上我们找连续子数组最大和 与 sum - 连续子数组最小和 之间的最大值就可以了。

    class Solution {
    public:
        int maxSubarraySumCircular(vector<int>& nums) {
            int sum = 0, currMaxSum = 0, currMinSum = 0;
            int gMaxSum = INT_MIN, gMinSum = INT_MAX;
            for (auto num : nums) {
                sum += num;
                currMaxSum = max(currMaxSum + num, num);
                gMaxSum = max(gMaxSum, currMaxSum);
                currMinSum = min(currMinSum + num, num);
                gMinSum = min(gMinSum, currMinSum);
            }
            //if all negative
            if (gMinSum == sum) return gMaxSum;
            return max(gMaxSum, sum - gMinSum);
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    解法2:单调队列+滑动窗口。但很不容易调通。
    注意这里的滑动窗口的left就是dq.front,右窗口就是i。也就是说,滑动窗口的大小就相当于是i - dq.front。
    什么时候调整左窗口? while (i - dq.front() > n) dq.pop_front();

    class Solution {
    public:
        /**
         * @param a: the array
         * @return: Maximum Sum Circular Subarray
         */
        int maxSubarraySumCircular(vector<int> &a) {
            int n = a.size(), n2 = (n << 1);
            int res = INT_MIN;
            deque<int> dq; //monotonous queue
            vector<int> nums2(n2, 0);
            vector<int> presums(n2 + 1, 0);
            for (int i = 0; i < n2; i++) {
                nums2[i] = a[i % n];
            }        
            for (int i = 1; i <= n2; i++) {
                presums[i] = presums[i - 1] + nums2[i - 1];
            }
            for (int i = 1; i <= n2; i++) {
                while (!dq.empty() && presums[dq.back()] > presums[i]) {
                    dq.pop_back();
                }
                dq.push_back(i);
                while (i - dq.front() > n) dq.pop_front();
                
                if (!dq.empty()) {
                    if (i == dq.front()) res = max(res, presums[i] - presums[i - 1]); //当输入全为负数时,处理不一样。
                    else res = max(res, presums[i] - presums[dq.front()]);
                } else {
                    res = max(res, presums[i]);
                }
    
            }
            return res;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
  • 相关阅读:
    搞定面试官 - 你可以介绍一下在 MySQL 中,哪些情况下 索引会失效嘛?
    【MTK】【WIFI】手机和综测仪器误差在5db左右误差
    MySQL-(3)
    从零开始写 Docker(四)---使用 pivotRoot 切换 rootfs 实现文件系统隔离
    UEditorPlus v2.4.0发布 Word图片粘贴重构,功能样式优化
    【DL】基于卷积神经网络的一维数据二分类预测
    docker部署mysql8避坑版,看这一篇就够了
    关于接口测试问题,这些文章推荐你反复看看
    【数据结构】树和二叉树的概念及结构
    IOC和DI入门案例
  • 原文地址:https://blog.csdn.net/roufoo/article/details/133132318