Reputation: 10364
Use Integer.MAX_VALUE
in order to consistently return a large number for the purposes of comparison.
Integer.MAX_VALUE
is returning a negative number.
In the sample code values are saved into a 2D table in order to find the minimum amount of coins required to make up a given amount.
Using Integer.MAX_VALUE
-2147483647
is being derived from Integer.MAX_VALUE
.
fun main() {
// Steps - Iterative/bottom-up
// 1. Create a 2D table: Rows = Denominations(Denoms), Columns = Amount(Amt)
// 2. Store min # of coins in at [R][C] = Min(currentDenomMin, previousDenomMin)
// a. currentDenomMin = [R][C - coins.get(R)] + 1
// b. previousDenomMin = [R - 1][C]
// 3. Return minCount or -1 for table[coins.size - 1, Amt].
println("Min count: ${coinChange(intArrayOf(2), 3)}")
}
lateinit var table: Array<IntArray>
lateinit var mCoins: IntArray
private val maxValue = Integer.MAX_VALUE
fun coinChange(coins: IntArray, amt: Int): Int {
table = Array(coins.size, { IntArray(amt + 1) })
mCoins = coins
coins.sort()
buildMinCounts(amt)
val minCount = table[coins.size - 1][amt]
return if (minCount == maxValue) -1 else minCount
}
fun buildMinCounts(amt: Int) {
for (r in 0..mCoins.size - 1) {
for (c in 0..amt) {
val currentDenomValue = mCoins.get(r)
val currentDenomMin = getDenomMin(r, c - currentDenomValue) + 1
val previousDenomMin = getDenomMin(r - 1, c)
if (c == 0) {
table[r][c] = 0
} else table[r][c] = Math.min(currentDenomMin, previousDenomMin)
}
}
}
fun getDenomMin(r: Int, c: Int): Int {
if (r < 0 || c < 0) return maxValue
else return table[r][c]
}
fun printT(amt: Int) {
for (r in 0..mCoins.size - 1) {
for (c in 0..amt) {
print("${table[r][c]} ")
}
println("")
}
}
Using 999999999
as the maxValue
instead
Works as expected.
fun main() {
println("Min count: ${coinChange(intArrayOf(2), 3)}")
}
lateinit var table: Array<IntArray>
lateinit var mCoins: IntArray
private val maxValue = 999999999
fun coinChange(coins: IntArray, amt: Int): Int {
table = Array(coins.size, { IntArray(amt + 1) })
mCoins = coins
coins.sort()
buildMinCounts(amt)
val minCount = table[coins.size - 1][amt]
return if (minCount == maxValue) -1 else minCount
}
fun buildMinCounts(amt: Int) {
for (r in 0..mCoins.size - 1) {
for (c in 0..amt) {
val currentDenomValue = mCoins.get(r)
val currentDenomMin = getDenomMin(r, c - currentDenomValue) + 1
val previousDenomMin = getDenomMin(r - 1, c)
if (c == 0) {
table[r][c] = 0
} else table[r][c] = Math.min(currentDenomMin, previousDenomMin)
}
}
}
fun getDenomMin(r: Int, c: Int): Int {
if (r < 0 || c < 0) return maxValue
else return table[r][c]
}
fun printT(amt: Int) {
for (r in 0..mCoins.size - 1) {
for (c in 0..amt) {
print("${table[r][c]} ")
}
println("")
}
}
Upvotes: 2
Views: 1642
Reputation: 1577
It's because of overflow. getDenomMin(r, c - currentDenomValue) + 1
returns Integer.MAX_VALUE + 1
which causes overflow. There are two ways to avoid this:
Change maxValue
to something such that it doesn't overflows and is actually is the maximum. For example, you have array of size 10^5 containing integers between 1 and 10^9. Now maximum possible sum will 10^5 * 10^9 which is 10^14 so we can set maxValue
to any value greater than or equal to 10^14. In your case you can set it to something like 10^5 because you need count not sum which can be at max number of coins available.
val currentDenomMin = getDenomMin(r, c - currentDenomValue) + 1
Before adding 1 you can type it to Long so that it doesn't overflow.
val currentDenomMin = getDenomMin(r, c - currentDenomValue).toLong + 1
Upvotes: 3