给定一个数组,数组中任意数量1-9的数,可以组合成10的方案有多少个

以下只是用我自己理解的方法解决的,有更优雅的方法可以留言,我也可以学习下。

JS写法

/**
 *  给定一个数组,数组中任意数量1-9的数,可以组合成10的方案有多少个
 */
const test1 = [1, 1, 1, 1, 2, 2, 3, 4, 5, 5, 6, 8, 9]
const resMap = []
const counter = arrEleCounter(test1)
peer(counter, 10, '')
const removeDuplicateResult = resMap.map(allItem => allItem.split('+').map(removeDuplicateItem => Number(removeDuplicateItem)).sort().join('+'))
/*以+为分割符,然后Number化,然后排序,再转为string*/
const mySet = new Set(removeDuplicateResult)

console.log('各个数字出现的个数:', counter)
console.log('大于5的只显示一次')
console.log('未去重结果详情:', resMap)
console.log('未去重结果个数:', resMap.length)
console.log('去重之后的结果详情:', mySet)
console.log('去重之后的结果个数:', mySet.size)
//深拷贝
function deepCopy(o) {
     
  if (o instanceof Array) {
      // 先判断Array
    var n = []
    for (var i = 0; i < o.length; ++i) {
     
      n[i] = deepCopy(o[i])
    }
    return n
  } else if (o instanceof Object) {
     
    var n = {
     }
    for (var i in o) {
     
      n[i] = deepCopy(o[i])
    }
    return n
  } else {
     
    return o
  }
}
// 统计每个数字出现的次数
function arrEleCounter(arr) {
     
  var b = {
     }
  for (let i = 0; i < arr.length; i++) {
     
    b[arr[i]] = (b[arr[i]] + 1) || 1
    // 大于5的数 个数已经没有意义了
    if (arr[i] > 5) {
     
      b[arr[i]] = 1
    }
  }
  return b
}
// 递归分解
function peer(obj, num, str) {
     
  for (const item in obj) {
     
    const item_num = Number(item)// string转为number
    if (item_num < (num + 1) / 2) {
     
      for (let i = 1; i < obj[item] + 1; i++) {
     
        const diff = num - item_num * i
        if (diff <= 0) {
     
          return false
        }
        const restObj = deepCopy(obj)
        restObj[item] = restObj[item] - i
        if (restObj[item] === 0) {
     
          delete restObj[item]
        }
        const obj_keys = Object.keys(restObj)
        if (obj_keys.includes(diff.toString())) {
     
          const compression = `${
       str}${
       item}+${
       diff}`
          if (eval(compression) === 10) {
     
            if (compression.substr(0, 1) > 1 && compression.substr(2, 1) < 5) {
     
              return false
            }
            resMap.push(compression)
            peer(restObj, diff, `${
       str}${
       item}+`)
          }
        } else {
     
          delete restObj[item]
          peer(restObj, diff, `${
       str}${
       item}+`)
        }
      }
    }
  }
}

运行结果

去重之后的结果详情: Set { '1+9',
  '1+1+8',
  '1+1+1+2+5',
  '1+1+1+2+2+3',
  '1+1+1+3+4',
  '1+1+2+6',
  '1+1+1+1+2+4',
  '1+1+2+2+4',
  '1+1+3+5',
  '1+2+3+4',
  '1+3+6',
  '1+4+5',
  '2+8',
  '4+6',
  '5+5' }
去重之后的结果个数: 15

更优雅的写法

java

常见算法 - 从给定数组中选取任意个数(可重复),使其和为给定值。

从给定有序数组中选取任意个数(可重复),使其和为给定值(leetcode39):

思路:回溯法的练习题。因为可以重复,注意递归调用时可以从当前位置开始取。。

从给定无序数组中选取任意个数(不可重复),使其和为给定值(leetcode40):

思路:回溯法的练习题,按照上题思路,可以先将数组排序,不同点是因为不可以重复,递归调用要从当前位置的下一个数开始取。

你可能感兴趣的:(JavaScript,算法,给定一个数组,数组中任意数量1-9的数,可以组合成10的方案有多少个)