-
Notifications
You must be signed in to change notification settings - Fork 10
Expand file tree
/
Copy pathsumN.js
More file actions
64 lines (59 loc) · 1.69 KB
/
Copy pathsumN.js
File metadata and controls
64 lines (59 loc) · 1.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/**
* @desc 求一个数组中n个数字和为sum的解 - 递归求解
* @param {Array} array 原数组
* @param {Number} n 需要选择几个数(递归时:还需选择几个数)
* @param {Number} sum 需要的和(递归时:剩余和)
* @param {Number} i 指针 当前选到第几个元素
* @param Array decisions 决策数组 只要第一次满足就会直接返回 故只求一个解
* @return decisions 只求一个解
*/
const sumNRecursion = (array, n, sum, i = 0, decisions = []) => {
// console.log(sum, i, n, decisions)
if (sum === 0) {
return decisions
}
if (i === array.length || n === 0) {
return null
}
return sumNRecursion(array, n - 1, sum - array[i], i + 1, decisions.concat(array[i])) || sumNRecursion(array, n, sum, i + 1, decisions)
}
// Test
console.log(sumNRecursion([1, 2, 3, 4, 5], 3, 10))
/**
* @desc 求一个数组中n个数字和为sum的解 - 利用位运算
* @param {Array} array 原数组
* @param {Number} n 需要选择几个数
* @param {Number} m 需要的和
* @return decisions 求所有解
*/
const sumNBitOperation = (array, n, m) => {
let ret = []
let max = 1 << array.length
for (let i = 0; i < max; i++) {
const { sum, p } = sumByBinaryCode(array, i)
if (sum === m && p.length === n) {
// return p
ret.push(p)
}
}
// return null
return ret
}
const sumByBinaryCode = (array, code) => {
const p = []
let sum = 0
for (let i = 0; i < array.length; i++) {
if (code & (1 << i)) {
sum += array[i]
p.push(array[i])
}
}
// console.log({ sum, p })
return { sum, p }
}
// Test
console.log(sumNBitOperation([1, 2, 3, 4, 5], 3, 10))
export {
sumNRecursion,
sumNBitOperation
}