📜  最大循环子数组和的Javascript程序(1)

📅  最后修改于: 2023-12-03 15:40:15.104000             🧑  作者: Mango

最大循环子数组和的Javascript程序

程序介绍

本程序基于贪心算法实现,用于计算一个数组中最大的循环子数组和,即将数组首尾相连,找出其中连续元素和的最大值。

程序思路
  1. 对于一个非空数组,先计算其最大子数组和,然后再计算其最小子数组和。
  2. 计算数组的总和,然后用总和减去最小子数组和,得到首尾相连的最大子数组和。
  3. 将首尾相连的最大子数组和与非首尾相连的最大子数组和进行比较,取其中较大值。
代码实现
/**
 * 计算最大循环子数组和
 * @param {Array} arr 需要计算的数组
 * @return {Number} 最大循环子数组和
 */
function getMaxCircularSubarraySum(arr) {
    // 计算数组的总和
    let sum = arr.reduce((acc, cur) => { return acc + cur }, 0);

    // 计算最大子数组和
    let maxSubarraySum = getMaxSubarraySum(arr);

    // 计算最小子数组和
    let minSubarraySum = getMinSubarraySum(arr);

    // 计算首尾相连的最大子数组和
    let maxCircularSubarraySum = sum - minSubarraySum;

    // 比较首尾相连的最大子数组和与非首尾相连的最大子数组和,并返回较大值
    return Math.max(maxSubarraySum, maxCircularSubarraySum);
}

/**
 * 计算最大子数组和
 * @param {Array} arr 需要计算的数组
 * @return {Number} 最大子数组和
 */
function getMaxSubarraySum(arr) {
    let n = arr.length;
    let maxSum = arr[0], curSum = arr[0];
    for (let i = 1; i < n; i++) {
        curSum = Math.max(curSum + arr[i], arr[i]);
        maxSum = Math.max(maxSum, curSum);
    }
    return maxSum;
}

/**
 * 计算最小子数组和
 * @param {Array} arr 需要计算的数组
 * @return {Number} 最小子数组和
 */
function getMinSubarraySum(arr) {
    let n = arr.length;
    let minSum = arr[0], curSum = arr[0];
    for (let i = 1; i < n; i++) {
        curSum = Math.min(curSum + arr[i], arr[i]);
        minSum = Math.min(minSum, curSum);
    }
    return minSum;
}
测试样例
// 测试样例1
let arr1 = [1, -2, 3, -2];
console.log(getMaxCircularSubarraySum(arr1)); // 3

// 测试样例2
let arr2 = [5, -3, 5];
console.log(getMaxCircularSubarraySum(arr2)); // 10

// 测试样例3
let arr3 = [-20000, 1, -20000, 1, -20000];
console.log(getMaxCircularSubarraySum(arr3)); // 2

// 测试样例4
let arr4 = [1, -1, 1, -1, 1, -1, 1];
console.log(getMaxCircularSubarraySum(arr4)); // 3
总结

本程序基于贪心算法实现,计算最大循环子数组和的时间复杂度为O(n),空间复杂度为O(1)。在计算过程中,需要计算数组的总和、最大子数组和、最小子数组和等中间结果,但这些计算均是基于最大子数组和的计算结果,因此不需要使用额外的空间对它们进行存储,只需要用三个变量即可实现。