JavaScript实现从数组中选出和等于固定值的n个数

下面是JavaScript实现从数组中选出和等于固定值的n个数的完整攻略:

问题描述

假设有一个数组arr和一个固定值target,如何从arr中选出n个数,使得这n个数的和等于target。

解决方案

1. 暴力破解

最简单粗暴的方法当然是暴力破解,即枚举所有的 n 个数的组合情况,计算它们的和,如果等于 target,则返回这个组合。但其时间复杂度为O($\binom{n}{len(arr)}$),不太适合大规模数据。示例代码:

function findNNumbers(arr, target, n) {
  const getAllCombs = (arr, n) => {
    if (n === 1) {
      return arr.map(item => [item]);
    }
    let allCombs = [];
    for (let i = 0; i < arr.length - n + 1; i++) {
      const comb = getAllCombs(arr.slice(i + 1), n - 1).map(item => [arr[i], ...item]);
      allCombs = [...allCombs, ...comb];
    }
    return allCombs;
  };
  const combs = getAllCombs(arr, n);
  return combs.find(comb => comb.reduce((a, b) => a + b, 0) === target);
}

const arr = [1, 3, 5, 7];
const target = 10;
const n = 2;
console.log(findNNumbers(arr, target, n)); // [3,7]

2. 动态规划

在暴力破解的基础上进行优化,可以采用动态规划的思想。定义 dp[i][j][k] 表示前i个数中选j个数的和是否等于k,若dp[i][j][k]为true,则表示存在一组数的和等于k。则有以下状态转移方程:

  • dp[i][j][k] = dp[i-1][j][k] // 不选第i个数
  • dp[i][j][k] = dp[i-1][j-1][k-arr[i]] // 选第i个数

时间复杂度为$O(ntargetlen(arr))$,可以通过本题。示例代码:

function findNNumbers(arr, target, n) {
  const results = [];
  const dp = Array.from({ length: arr.length + 1 }, () => Array.from({ length: n + 1 }, () => Array.from({ length: target + 1 }, () => false)));
  for (let i = 1; i <= arr.length; i++) {
    for (let j = 1; j <= Math.min(i, n); j++) {
      for (let k = 1; k <= target; k++) {
        dp[i][j][k] = dp[i - 1][j][k];
        if (arr[i - 1] === k && j === 1) {
            dp[i][j][k] = true;
        }
        if (arr[i - 1] < k && j > 1) {
            dp[i][j][k] = dp[i - 1][j - 1][k - arr[i - 1]];
        }
        if (dp[i][j][k] && j === n && k === target) {
            const result = [];
            let x = i, y = j, z = k;
            while (x > 0 && y > 0 && z > 0) {
              if (dp[x][y][z]) {
                result.unshift(arr[x - 1]);
                y--;
                z -= arr[x - 1];
              }
              x--;
            }
            results.push(result);
        }
      }
    }
  }
  return results;
}

const arr = [1, 3, 5, 7, 9];
const target = 10;
const n = 3;
console.log(findNNumbers(arr, target, n)); // [ [3, 5, 2], [7, 2, 1] ]

这里假设找到所有可能的组合,如果只要其中任意一种,则可以在 dp 中用一个boolean变量标识是否找到即可。

3. 回溯法

利用回溯法可以找到所有符合条件的组合,而不仅是其中任意一种。示例代码:

function findNNumbers(arr, target, n) {
  const results = [];
  const dfs = (startIndex, path, sum) => {
    if (path.length === n && sum === target) {
      results.push([...path]);
      return;
    }
    for (let i = startIndex; i < arr.length && sum + arr[i] <= target && path.length + arr.length - i >= n; i++) {
      path.push(arr[i]);
      dfs(i + 1, path, sum + arr[i]);
      path.pop();
    }
  }
  dfs(0, [], 0);
  return results;
}

const arr = [1, 3, 5, 7, 9];
const target = 10;
const n = 3;
console.log(findNNumbers(arr, target, n)); // [ [1, 5, 4], [1, 3, 6], [1, 9, 0], [3, 5, 2], [7, 2, 1] ]

其中,startIndex 表示每一轮开始枚举的起点,path 是当前已选的数列,sum 表示当前已选的数列的和。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JavaScript实现从数组中选出和等于固定值的n个数 - Python技术站

(0)
上一篇 2023年6月25日
下一篇 2023年6月25日

相关文章

  • Win11 22H2 Build 22621.675更新补丁KB5019509 Release预览版发布(附完整更新日志)

    Win11 22H2 Build 22621.675 更新补丁 KB5019509 Release 预览版发布 更新概述 Win11 22H2 Build 22621.675 更新补丁 KB5019509 Release 预览版是针对 Windows 11 操作系统的最新更新补丁。该补丁旨在修复一些已知的问题,并提供性能改进和安全增强。本文将详细介绍该更新补…

    other 2023年8月3日
    00
  • linux之jq

    Linux之jq的完整攻略 jq是一个命令行工具,用于处理JSON格式的数据。它可以帮助用户快速地查询、过滤、转换和格式化JSON数据。本文将详细讲解jq的使用方法,并提供两个示例说明。 1. 安装jq 在Linux系统中,可以使用以下命令安装jq: sudo apt-get install jq 2. jq的基本用法 2.1 查询JSON数据 可以使用jq…

    other 2023年5月9日
    00
  • Java入门绊脚石之Override和Overload的区别详解

    Java入门绊脚石之Override和Overload的区别详解 什么是Override和Overload? Override和Overload都是Java中的重载(overload)机制,它们都允许在一个类中有多个同名的方法,但是它们有不同的应用场景。 Override指子类继承父类之后,重新定义该方法的实现过程的行为,方法的名称、参数类型、返回值类型必须…

    other 2023年6月26日
    00
  • 晨枫u盘启动工具安装原版Win7的两种方法(32位64位系统通用)

    晨枫U盘启动工具安装原版Win7的两种方法(32位/64位系统通用) 方法一:使用晨枫U盘启动工具制作启动盘 首先,确保你已经下载了晨枫U盘启动工具,并将其安装到你的电脑上。 插入一个空白的U盘到你的电脑上。 打开晨枫U盘启动工具,并按照以下步骤进行操作: 在主界面上,选择你的U盘所在的盘符。 在“启动模式”下拉菜单中,选择“Windows 7”。 在“镜像…

    other 2023年7月28日
    00
  • 详解vue.js中.native修饰符

    以下是关于“详解Vue.js中.native修饰符”的完整攻略: Vue.js简介 Vue.js是一款流行的JavaScript框架用于构建交互式的Web界面。Vue.js采用组件化的开发方式,可以将页面拆分成多个组件,提高的可维性和可重用性。 .native修饰符 在Vue.js中,可以使用修饰符来改变指令的行为。其中,.native饰符用于监听组件根元素…

    other 2023年5月9日
    00
  • Android内存泄漏终极解决篇(下)

    下面是对于“Android内存泄漏终极解决篇(下)”的完整攻略。 需要解决的问题 我们很容易在开发Android应用时遇到内存泄漏的问题,这一问题可能是由于合理的业务逻辑与错误的内存使用方式组合在一起导致的。内存泄露会导致应用程序的性能降低,甚至会崩溃。因此,在开发阶段发现并解决内存泄漏问题非常重要。 解决内存泄漏的步骤 步骤1:分析内存泄漏 首先,需要找到…

    other 2023年6月26日
    00
  • extundelete教程(完整版)

    extundelete教程(完整版) 简介 extundelete是一款用于恢复已删除文件的工具,支持Linux文件系统中的ext2、ext3和ext4分区,可用于修复遗失的文件、目录和甚至Ext4的日志文件。该工具使用起来比较简单,且在Linux系统中使用广泛,具有一定的实用性和参考价值。 准备工作 在使用extundelete之前,我们需要准备好以下工具…

    其他 2023年3月29日
    00
  • MySql服务未知原因消失解决方法

    确定MySql服务是否消失 首先,需要确定MySql服务是否真的消失了。你需要在命令提示符下使用以下命令查看服务状态: net start mysql 如果服务被正常安装,输出结果将为服务的状态,如“正在启动”或“正在运行”。但是,如果服务未安装或已卸载,则会收到错误消息,表明服务不存在。 在此情况下,你需要在本地计算机上重新安装Mysql服务。如果你已经尝…

    other 2023年6月27日
    00
合作推广
合作推广
分享本页
返回顶部