使用Kadane算法在JavaScript中查找子数组的最大和


探索复杂的算法是释放JavaScript编程真正潜力的关键,尤其是在解决复杂的计算挑战方面。在这些算法中,Kadane算法作为一种强大的工具脱颖而出,可以有效地找到数组中子数组的最大和。这种卓越的技术允许开发人员优化他们的代码,并在处理大型数据集时提高应用程序的性能。在本文中,我们将深入探讨Kadane算法的细节,揭示其内部工作原理,并展示其在解决JavaScript中查找子数组最大和任务中的有效性。通过掌握底层原理并在实践中实现此算法,开发人员可以提升他们的编程技能,并征服计算问题解决领域。

问题陈述

在JavaScript中实现Kadane算法,以查找给定数组中子数组的最大和。

示例输入:

arr = [-2, 1, -3, 4, -1, 2, 1, -5, 4]

示例输出:

给定数组中子数组的最大和是6。最大和的子数组是[4, -1, 2, 1]。

方法

在本文中,我们将看到几种在JavaScript中解决上述问题陈述的不同方法:

  • 朴素方法

  • Kadane算法(动态规划)

  • 带有索引的Kadane算法

方法1:朴素方法

为了找到子数组的最大和,朴素方法将maxSum初始化为-Infinity,并迭代每个索引i,表示子数组的起始索引。对于每个起始索引i,它从i迭代到数组的末尾,表示子数组的结束索引。计算当前子数组的和,如果它大于maxSum,则更新maxSum。最后,在两个循环完成后返回最终的maxSum。

示例

在给定的代码中,变量maxSum最初设置为-Infinity,以确保遇到的任何正数和都将被视为新的最大值。外循环遍历数组的每个索引i,表示子数组的起始索引。内循环从起始索引i迭代到数组的末尾,表示子数组的结束索引。在内循环的每次迭代中,变量sum跟踪当前子数组的和。使用Math.max(maxSum, sum)比较当前最大和与当前子数组的和来更新最大和。最后,在两个循环完成后,返回最终的最大和。

function maxSubarraySum(arr) {
   let maxSum = -Infinity;
   for (let i = 0; i < arr.length; i++) {
      let sum = 0;

      for (let j = i; j < arr.length; j++) {
         sum += arr[j];
         maxSum = Math.max(maxSum, sum);
      }
   }
   return maxSum;
}
const arr = [-2, 1, -3, 4, -1, 2, 1, -5, 4];
console.log(`Maximum Sum: ${maxSubarraySum(arr)}`);

输出

以下是控制台输出:

Maximum Sum: 6

方法2:Kadane算法(动态规划)

Kadane算法是一种动态规划方法,用于在数组中查找最大子数组和。它首先将两个变量maxEndingHere和maxSoFar分别初始化为0和-Infinity。然后,它迭代数组的每个索引i,通过比较当前元素arr[i]和以i-1结尾的先前子数组的和加上当前元素来更新maxEndingHere。该算法还通过比较当前maxSoFar和maxEndingHere来更新maxSoFar。最后,在循环完成后,该算法返回最终的maxSoFar作为最大子数组和。

示例

在提供的代码中,maxEndingHere和maxSoFar的初始值分别设置为0和-Infinity。实现一个循环来迭代数组的每个索引i。在每次迭代中,使用Math.max(arr[i], maxEndingHere + arr[i])更新maxEndingHere。此比较确定扩展当前子数组(通过添加arr[i])是否会产生更大的和,或者从arr[i]开始新的子数组是否会产生更大的和。为了确保maxSoFar始终存储迄今为止找到的最大和,通过使用Math.max(maxSoFar, maxEndingHere)比较当前maxSoFar与maxEndingHere来更新它。最后,循环完成后,返回最终的最大和(maxSoFar)。

function maxSubarraySum(arr) {
   let maxEndingHere = 0;
   let maxSoFar = -Infinity;

   for (let i = 0; i < arr.length; i++) {
      maxEndingHere = Math.max(arr[i], maxEndingHere + arr[i]);
      maxSoFar = Math.max(maxSoFar, maxEndingHere);
   }
   return maxSoFar;
}
const arr = [-2, 1, -3, 4, -1, 2, 1, -5, 4];
console.log(`Maximum Sum: ${maxSubarraySum(arr)}`);

输出

以下是控制台输出:

Maximum Sum: 6

方法3:带有索引的Kadane算法

Kadane算法是一种查找数组中子数组最大和的技术。它涉及初始化变量,例如maxEndingHere、maxSoFar、start、end和tempStart。通过迭代数组的每个索引,该算法比较扩展当前子数组(通过添加arr[i]的值)是否比从arr[i]开始新的子数组产生更大的和。如果扩展子数组更有利,则相应更新maxEndingHere和tempStart。该算法还根据找到的最大和及其各自的索引更新maxSoFar、start和end。最终,该算法返回一个包含最大和及其相应子数组的对象。

示例

在给定的代码中,变量例如maxEndingHere、maxSoFar、start、end和tempStart的初始化方式与之前相同。一个循环迭代数组的每个索引i。在循环内,if语句比较扩展当前子数组(通过添加arr[i])的和与从arr[i]开始新的子数组的和。如果扩展产生更大的和,则更新maxEndingHere和tempStart。最大和和相应的索引以与之前相同的方式更新。最后,该函数返回一个包含属性maxSum(表示最大和)和subarray(表示相应子数组)的对象。

function maxSubarraySum(arr) {
   let maxEndingHere = 0;
   let maxSoFar = -Infinity;
   let start = 0;
   let end = 0;
   let tempStart = 0;

   for (let i = 0; i < arr.length; i++) {
      if (arr[i] > maxEndingHere + arr[i]) {
         tempStart = i;
         maxEndingHere = arr[i];
      } else {
         maxEndingHere += arr[i];
      }

      if (maxEndingHere > maxSoFar) {
         start = tempStart;
         end = i;
         maxSoFar = maxEndingHere;
      }
   }

   return {
      maxSum: maxSoFar,
      subarray: arr.slice(start, end + 1)
   };
}
 
const arr = [-2, 1, -3, 4, -1, 2, 1, -5, 4];
const res = maxSubarraySum(arr);
console.log(`Maximum Sum: ${res.maxSum}`);
console.log(`Maximum Sum Subarray: ${res.subarray}`);

输出

以下是控制台输出:

Maximum Sum: 6
Maximum Sum Subarray: 4,-1,2,1

结论

总之,使用Kadane算法来确定JavaScript中子数组的最大和,可以是一种提高效率和优化计算资源的有效技术。通过使用这种深奥的算法,开发人员可以释放隐藏的潜力,解开复杂的数据模式并提取有价值的见解。实现此算法可能需要一定的技巧,但其回报是多方面的:加速性能、简化操作以及在识别最大子数组和方面的无与伦比的精度。总之,Kadane算法的深奥能力使JavaScript程序员能够超越传统界限,并释放其应用程序的真正潜力。

更新于:2023年8月4日

394 次浏览

启动您的职业生涯

完成课程后获得认证

开始
广告