查找总和等于数字的所有子数组?JavaScript(滑动窗口算法)

我们得到一个数字数组和一个数字;我们的工作是编写一个函数,该函数返回所有子数组的数组,这些子数组的总和等于第二个参数提供的数字。

例如-

const arr = [23, 5, 1, 34, 12, 67, 9, 31, 6, 7, 27];
const sum = 40;
console.log(requiredSum(arr, sum));

应该输出以下数组-

[ [ 5, 1, 34 ], [ 9, 31 ], [ 6, 7, 27 ] ]

因为这3个子阵列中的每一个加起来等于40。

滑动窗口算法(线性时间)

当需要我们在满足特定条件的字符串中查找数组/子字符串中的子数组时,通常使用此算法。这个问题非常适合滑动窗口算法。

滑动窗口算法恰如其名,我们创建了一个窗口,该窗口不过是原始数组的子数组。该窗口试图通过增加或减少来获得稳定性。

稳定性是指问题中指定的条件(例如,此处累加一个特定的数字)。一旦它变得稳定,我们记录窗口并继续滑动它。通常,在90%的问题中,我们从左侧开始窗口并保持滑动,直到其末尾到达数组/字符串的末尾。

让我们看一下使自己更熟悉滑动Windows算法的代码。

示例

const arr = [23, 5, 1, 34, 12, 67, 9, 31, 6, 7, 27];
const sum = 40;
const findSub = (arr, sum) => {
   const required = [];
   for(let start = 0, end = 0, s = 0; end <= arr.length || s > sum ; ){
      if(s < sum){
         s += arr[end];
         end++;
      }else if(s > sum){
         s -= arr[start];
         start++;
      }else{
         required.push(arr.slice(start, end));
         s -= arr[start];
         s += arr[end];
         start++;
         end++;
      };
   };
   return required;
};
console.log(findSub(arr, sum));

开始和结束变量表示窗口在不同点的开始和结束位置。

最初两者都从0开始,然后如果所需的总和小于给定的总和,我们增加了窗口的大小,如果所需的总和小于给定的总和,则减小了窗口的大小,并且在任何时候两者都相等,我们将该子数组推入所需的数组。并将窗口向右移动单位距离。

输出结果

此代码在控制台中的输出将为-

[ [ 5, 1, 34 ], [ 9, 31 ], [ 6, 7, 27 ] ]