給定一個數組,數組中任意數量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):

思路:回溯法的練習題,按照上題思路,可以先將數組排序,不同點是因爲不可以重複,遞歸調用要從當前位置的下一個數開始取。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章