-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathKSum.kt
96 lines (87 loc) · 2.51 KB
/
KSum.kt
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package algorithmdesignmanualbook.sorting
import kotlin.test.assertTrue
/**
* Given a set S of n integers and an integer T,
* give an algorithm to test whether k of the integers in S add up to T.
*
* [Another way](https://www.geeksforgeeks.org/find-the-k-th-permutation-sequence-of-first-n-natural-numbers/)
*
* ### IDEA:
*
* ```
* For target=21, k=3 i.e. 21/3 and array:
*
* ! 5 ! 6 ! 8 ! 10 ! 12 !
*
* <------- 21/3 ------>
*
* ^ <--- 16/2 --->
*
* ^ <--- 10/1 --->
* ```
*/
class KSum(_input: Array<Int>, private val target: Int, private val k: Int) {
val result = mutableListOf<MutableList<Int>>()
// Sort it first
val array: Array<Int> = _input.sortedArray()
fun execute(): List<List<Int>> {
for (i in 0..array.lastIndex) {
val temp = mutableListOf<Int>()
kSumHelper(k, target, i, temp)
}
println(result)
return result
}
private fun kSumHelper(
remainingKCount: Int,
remainingSum: Int,
currentIndex: Int,
temp: MutableList<Int>
) {
// array out of bound
if (currentIndex > array.lastIndex) {
return
}
// Only 1 item remains
if (remainingKCount == 1) {
// When you have 1 item remaining, just find if from current index to end, there exists an item == [remainingSum]
if (array.sliceArray(currentIndex..array.lastIndex).contains(remainingSum)) {
temp.add(remainingSum)
// Since sum( [temp] + remainingSum ) == target
result.add(temp)
return
}
}
temp.add(array[currentIndex])
kSumHelper(
remainingKCount = remainingKCount - 1, // Since you consider current element, then decrease the [remainingKCount]
remainingSum = remainingSum - array[currentIndex], // Remove it from sum
currentIndex = currentIndex + 1,
temp = temp
)
}
}
fun main() {
val input = arrayOf(-4, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8)
run {
KSum(input, 6, 3).execute().forEach {
assertTrue {
it.sum() == 6 && it.size == 3
}
}
}
run {
KSum(input, 8, 2).execute().forEach {
assertTrue {
it.sum() == 8 && it.size == 2
}
}
}
run {
KSum(input, 11, 3).execute().forEach {
assertTrue {
it.sum() == 11 && it.size == 3
}
}
}
}