每日一题-数字分组求偶数和

数字分组求偶数和

1.问题描述

小M面对一组从 1 到 9 的数字,这些数字被分成多个小组,并从每个小组中选择一个数字组成一个新的数。目标是使得这个新数的各位数字之和为偶数。任务是计算出有多少种不同的分组和选择方法可以达到这一目标。

  • ​numbers​: 一个由多个整数字符串组成的列表,每个字符串可以视为一个数字组。小M需要从每个数字组中选择一个数字。

例如对于​​[123, 456, 789]​​​,14个符合条件的数为:​​147 149 158 167 169 248 257 259 268 347 349 358 367 369​​。


2.测试样例

样例1:

输入:​​numbers = [123, 456, 789]​​​输出:​​14​

样例2:

输入:​​numbers = [123456789]​​​输出:​​4​

样例3:

输入:​​numbers = [14329, 7568]​​​输出:​​10​


3.解题思路

根据题意可知,给定数组numbers中有若干个数字,每个数字代表一个分组(从最高位到各位的每个数字组成一组),从每个分组中各取一个数字进行相加,所得之和需要为偶数即可,需要输出有多少总排列组合。

对于每一组中选择的数字,具体是几并不重要,重要的是奇数还是偶数

对于样例1来说,

  1. 第一组中选择1和3是一样的,第二组中选择4和6是一样的,第三组中选择7和9是一样的,他们都是奇数
  2. 只用统计:第一组中选择1的结果 x 2 +第一组中选择2的结果
  3. 总结:每一组中选择奇数的结果 x 奇数的个数 + 每一组中选择偶数的结果 x 偶数的个数

结论:可以按照 2n来遍历,类似于 奇数/偶数,奇数/偶数,奇数/偶数,,,,,,, 还要保证其中奇数的个数是偶数个

对于样例1来说:

  1. 奇数+奇数+奇数(排除,奇数的个数是3,不是偶数个,最终结果一定是奇数,不符合题意)
  2. 奇数+奇数+偶数 = 2 x 1 x 1 = 2
  3. 奇数+偶数+偶数(排除)
  4. 奇数+偶数+奇数 = 2 x 2 x 2 = 8
  5. 偶数+奇数+奇数 =1 x 1 x 2 = 2
  6. 偶数+偶数+偶数 = 1 x 2 x 1 = 2

一共是 0 + 2 + 0 + 8 + 2 + 2 = 14个

对于样例2来说:

  1. 奇数(排除)
  2. 偶数 = 4

一共是 0 + 4 = 4个

对于样例3来说:

  1. 奇数+奇数 = 3 x 2 = 6
  2. 偶数+偶数 = 2 x 2 = 4

一共是 6 + 4 = 10个

4.具体代码

ini 复制代码
function solution(numbers) {
  // Please write your code here
  const n = numbers.length
  const arr = []
  for (let i = 0; i < n; i++) {
    const group = getOddsAndEvensOfGroup(numbers[i])
    arr.push(group)
  }
  /**对于样例1,arr = [
    [1, 2],
    [2, 1],
    [1, 2]
  ]
  **/
  const res = [] // 符合条件的奇偶排列,如6表示0b110 >> 奇数+奇数+偶数
  for (let i = 0; i < 2 ** n; i++) {
    let sum = 0 // 奇数个数需为偶数个即可
    for (let j = 0; j < n; j++) {
      sum += (i & (2 ** j)) === 0 ? 0 : 1
    }
    if (sum % 2 === 0) {
      res.push(i)
    }
  }
  let sum = 0
  for (let i = 0; i < res.length; i++) {
    let acc = 1
    for (let j = 0; j < n; j++) {
      const flag = (res[i] & (2 ** j)) === 0 ? 0 : 1 // 0则取偶数个数,1取奇数个数
      acc = acc * arr[j][flag]
    }
    sum += acc
  }

  return sum;
}

// 从一个group中获取偶数的个数和奇数的个数,如123返回[1, 2]
function getOddsAndEvensOfGroup(group) {
  const numbers = String(group).split('').map(chr => +chr)
  // 奇数个数
  const odds = numbers.reduce((acc, cur) => acc + (cur % 2), 0)
  // 偶数个数
  const evens = numbers.length - odds
  return [evens, odds]
}

function main() {
  // You can add more test cases here
  console.log(solution([123, 456, 789]) === 14);
  console.log(solution([123456789]) === 4);
  console.log(solution([14329, 7568]) === 10);
}

main();

5.运行结果

相关推荐
Sword993 天前
LangChain 实战08 - OutputParser
前端·人工智能·豆包marscode
Sword997 天前
LangChain 实战06 - 六大核心组件之Prompt(下)
前端·人工智能·豆包marscode
Sword999 天前
LangChain 实战04 - 六大核心组件之Model
人工智能·豆包marscode
稀土君12 天前
直播送礼啦!豆包MarsCode校园发布会即将上线!万元大奖,玩法多多先睹为快
前端·人工智能·豆包marscode
鼠鼠有出息23 天前
LangChain 实战课:开篇词——奇点时刻
豆包marscode