Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add kotlin codes for the chapter of greedy #1103

Merged
merged 8 commits into from
Mar 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions codes/kotlin/chapter_greedy/coin_change_greedy.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/**
* File: coin_change_greedy.kt
* Created Time: 2024-01-25
* Author: curtishd (1023632660@qq.com)
*/

package chapter_greedy

/* 零钱兑换:贪心 */
fun coinChangeGreedy(coins: IntArray, amt: Int): Int {
// 假设 coins 列表有序
var am = amt
var i = coins.size - 1
var count = 0
// 循环进行贪心选择,直到无剩余金额
while (am > 0) {
// 找到小于且最接近剩余金额的硬币
while (i > 0 && coins[i] > am) {
i--
}
// 选择 coins[i]
am -= coins[i]
count++
}
// 若未找到可行方案,则返回 -1
return if (am == 0) count else -1
}

/* Driver Code */
fun main() {
// 贪心:能够保证找到全局最优解
var coins = intArrayOf(1, 5, 10, 20, 50, 100)
var amt = 186
var res = coinChangeGreedy(coins, amt)
println("\ncoins = ${coins.contentToString()}, amt = $amt")
println("凑到 $amt 所需的最少硬币数量为 $res")

// 贪心:无法保证找到全局最优解
coins = intArrayOf(1, 20, 50)
amt = 60
res = coinChangeGreedy(coins, amt)
println("\ncoins = ${coins.contentToString()}, amt = $amt")
println("凑到 $amt 所需的最少硬币数量为 $res")
println("实际上需要的最少数量为 3 ,即 20 + 20 + 20")

// 贪心:无法保证找到全局最优解
coins = intArrayOf(1, 49, 50)
amt = 98
res = coinChangeGreedy(coins, amt)
println("\ncoins = ${coins.contentToString()}, amt = $amt")
println("凑到 $amt 所需的最少硬币数量为 $res")
println("实际上需要的最少数量为 2 ,即 49 + 49")
}
57 changes: 57 additions & 0 deletions codes/kotlin/chapter_greedy/fractional_knapsack.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/**
* File: fractional_knapsack.kt
* Created Time: 2024-01-25
* Author: curtishd (1023632660@qq.com)
*/

package chapter_greedy

import java.util.*

/* 物品 */
class Item(
val w: Int, // 物品
val v: Int // 物品价值
)

/* 分数背包:贪心 */
fun fractionalKnapsack(
wgt: IntArray,
value: IntArray,
c: Int
): Double {
// 创建物品列表,包含两个属性:重量、价值
var cap = c
val items = arrayOfNulls<Item>(wgt.size)
for (i in wgt.indices) {
items[i] = Item(wgt[i], value[i])
}
// 按照单位价值 item.v / item.w 从高到低进行排序
Arrays.sort(items, Comparator.comparingDouble { item: Item -> -(item.v.toDouble() / item.w) })
// 循环贪心选择
var res = 0.0
for (item in items) {
if (item!!.w <= cap) {
// 若剩余容量充足,则将当前物品整个装进背包
res += item.v.toDouble()
cap -= item.w
} else {
// 若剩余容量不足,则将当前物品的一部分装进背包
res += item.v.toDouble() / item.w * cap
// 已无剩余容量,因此跳出循环
break
}
}
return res
}

/* Driver Code */
fun main() {
val wgt = intArrayOf(10, 20, 30, 40, 50)
val values = intArrayOf(50, 120, 150, 210, 240)
val cap = 50

// 贪心算法
val res = fractionalKnapsack(wgt, values, cap)
println("不超过背包容量的最大物品价值为 $res")
}
41 changes: 41 additions & 0 deletions codes/kotlin/chapter_greedy/max_capacity.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/**
* File: max_capacity.kt
* Created Time: 2024-01-25
* Author: curtishd (1023632660@qq.com)
*/

package chapter_greedy

import kotlin.math.max
import kotlin.math.min

/* 最大容量:贪心 */
fun maxCapacity(ht: IntArray): Int {
// 初始化 i, j,使其分列数组两端
var i = 0
var j = ht.size - 1
// 初始最大容量为 0
var res = 0
// 循环贪心选择,直至两板相遇
while (i < j) {
// 更新最大容量
val cap = (min(ht[i].toDouble(), ht[j].toDouble()) * (j - i)).toInt()
res = max(res.toDouble(), cap.toDouble()).toInt()
// 向内移动短板
if (ht[i] < ht[j]) {
i++
} else {
j--
}
}
return res
}

/* Driver Code */
fun main() {
val ht = intArrayOf(3, 8, 5, 2, 7, 7, 3, 4)

// 贪心算法
val res = maxCapacity(ht)
println("最大容量为 $res")
}
39 changes: 39 additions & 0 deletions codes/kotlin/chapter_greedy/max_product_cutting.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* File: max_product_cutting.kt
* Created Time: 2024-01-25
* Author: curtishd (1023632660@qq.com)
*/

package chapter_greedy

import kotlin.math.pow

/* 最大切分乘积:贪心 */
fun maxProductCutting(n: Int): Int {
// 当 n <= 3 时,必须切分出一个 1
if (n <= 3) {
return 1 * (n - 1)
}
// 贪心地切分出 3 ,a 为 3 的个数,b 为余数
val a = n / 3
val b = n % 3
if (b == 1) {
// 当余数为 1 时,将一对 1 * 3 转化为 2 * 2
return 3.0.pow((a - 1).toDouble()).toInt() * 2 * 2
}
if (b == 2) {
// 当余数为 2 时,不做处理
return 3.0.pow(a.toDouble()).toInt() * 2 * 2
}
// 当余数为 0 时,不做处理
return 3.0.pow(a.toDouble()).toInt()
}

/* Driver Code */
fun main() {
val n = 58

// 贪心算法
val res = maxProductCutting(n)
println("最大切分乘积为 $res")
}