以下只是用我自己理解的方法解決的,有更優雅的方法可以留言,我也可以學習下。
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):
思路:回溯法的練習題,按照上題思路,可以先將數組排序,不同點是因爲不可以重複,遞歸調用要從當前位置的下一個數開始取。