mirror of
https://github.com/krahets/hello-algo.git
synced 2026-04-10 22:30:53 +08:00
Improve readability of kotlin code (#1233)
* style(kotlin): Improve kotlin codes readability. * remove redundant quotes.
This commit is contained in:
@@ -8,13 +8,14 @@ package chapter_dynamic_programming
|
||||
|
||||
/* 回溯 */
|
||||
fun backtrack(
|
||||
choices: List<Int>,
|
||||
choices: MutableList<Int>,
|
||||
state: Int,
|
||||
n: Int,
|
||||
res: MutableList<Int>
|
||||
) {
|
||||
// 当爬到第 n 阶时,方案数量加 1
|
||||
if (state == n) res[0] = res[0] + 1
|
||||
if (state == n)
|
||||
res[0] = res[0] + 1
|
||||
// 遍历所有选择
|
||||
for (choice in choices) {
|
||||
// 剪枝:不允许越过第 n 阶
|
||||
@@ -29,7 +30,7 @@ fun backtrack(
|
||||
fun climbingStairsBacktrack(n: Int): Int {
|
||||
val choices = mutableListOf(1, 2) // 可选择向上爬 1 阶或 2 阶
|
||||
val state = 0 // 从第 0 阶开始爬
|
||||
val res = ArrayList<Int>()
|
||||
val res = mutableListOf<Int>()
|
||||
res.add(0) // 使用 res[0] 记录方案数量
|
||||
backtrack(choices, state, n, res)
|
||||
return res[0]
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
|
||||
package chapter_dynamic_programming
|
||||
|
||||
import java.util.*
|
||||
|
||||
/* 记忆化搜索 */
|
||||
fun dfs(i: Int, mem: IntArray): Int {
|
||||
// 已知 dp[1] 和 dp[2] ,返回之
|
||||
@@ -25,7 +23,7 @@ fun dfs(i: Int, mem: IntArray): Int {
|
||||
fun climbingStairsDFSMem(n: Int): Int {
|
||||
// mem[i] 记录爬到第 i 阶的方案总数,-1 代表无记录
|
||||
val mem = IntArray(n + 1)
|
||||
Arrays.fill(mem, -1)
|
||||
mem.fill(-1)
|
||||
return dfs(n, mem)
|
||||
}
|
||||
|
||||
@@ -33,6 +31,6 @@ fun climbingStairsDFSMem(n: Int): Int {
|
||||
fun main() {
|
||||
val n = 9
|
||||
|
||||
val res: Int = climbingStairsDFSMem(n)
|
||||
val res = climbingStairsDFSMem(n)
|
||||
println("爬 $n 阶楼梯共有 $res 种方案")
|
||||
}
|
||||
@@ -27,9 +27,7 @@ fun climbingStairsDPComp(n: Int): Int {
|
||||
var a = 1
|
||||
var b = 2
|
||||
for (i in 3..n) {
|
||||
val tmp = b
|
||||
b += a
|
||||
a = tmp
|
||||
b += a.also { a = b }
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
package chapter_dynamic_programming
|
||||
|
||||
import java.util.*
|
||||
import kotlin.math.min
|
||||
|
||||
/* 零钱兑换:动态规划 */
|
||||
@@ -27,8 +26,7 @@ fun coinChangeDP(coins: IntArray, amt: Int): Int {
|
||||
dp[i][a] = dp[i - 1][a]
|
||||
} else {
|
||||
// 不选和选硬币 i 这两种方案的较小值
|
||||
dp[i][a] = min(dp[i - 1][a].toDouble(), (dp[i][a - coins[i - 1]] + 1).toDouble())
|
||||
.toInt()
|
||||
dp[i][a] = min(dp[i - 1][a], dp[i][a - coins[i - 1]] + 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -41,7 +39,7 @@ fun coinChangeDPComp(coins: IntArray, amt: Int): Int {
|
||||
val MAX = amt + 1
|
||||
// 初始化 dp 表
|
||||
val dp = IntArray(amt + 1)
|
||||
Arrays.fill(dp, MAX)
|
||||
dp.fill(MAX)
|
||||
dp[0] = 0
|
||||
// 状态转移
|
||||
for (i in 1..n) {
|
||||
@@ -51,7 +49,7 @@ fun coinChangeDPComp(coins: IntArray, amt: Int): Int {
|
||||
dp[a] = dp[a]
|
||||
} else {
|
||||
// 不选和选硬币 i 这两种方案的较小值
|
||||
dp[a] = min(dp[a].toDouble(), (dp[a - coins[i - 1]] + 1).toDouble()).toInt()
|
||||
dp[a] = min(dp[a], dp[a - coins[i - 1]] + 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -70,4 +68,4 @@ fun main() {
|
||||
// 空间优化后的动态规划
|
||||
res = coinChangeDPComp(coins, amt)
|
||||
println("凑到目标金额所需的最少硬币数量为 $res")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
package chapter_dynamic_programming
|
||||
|
||||
import java.util.*
|
||||
import kotlin.math.min
|
||||
|
||||
/* 编辑距离:暴力搜索 */
|
||||
@@ -29,7 +28,7 @@ fun editDistanceDFS(
|
||||
val delete = editDistanceDFS(s, t, i - 1, j)
|
||||
val replace = editDistanceDFS(s, t, i - 1, j - 1)
|
||||
// 返回最少编辑步数
|
||||
return (min(min(insert.toDouble(), delete.toDouble()), replace.toDouble()) + 1).toInt()
|
||||
return min(min(insert, delete), replace) + 1
|
||||
}
|
||||
|
||||
/* 编辑距离:记忆化搜索 */
|
||||
@@ -55,7 +54,7 @@ fun editDistanceDFSMem(
|
||||
val delete = editDistanceDFSMem(s, t, mem, i - 1, j)
|
||||
val replace = editDistanceDFSMem(s, t, mem, i - 1, j - 1)
|
||||
// 记录并返回最少编辑步数
|
||||
mem[i][j] = (min(min(insert.toDouble(), delete.toDouble()), replace.toDouble()) + 1).toInt()
|
||||
mem[i][j] = min(min(insert, delete), replace) + 1
|
||||
return mem[i][j]
|
||||
}
|
||||
|
||||
@@ -79,11 +78,7 @@ fun editDistanceDP(s: String, t: String): Int {
|
||||
dp[i][j] = dp[i - 1][j - 1]
|
||||
} else {
|
||||
// 最少编辑步数 = 插入、删除、替换这三种操作的最少编辑步数 + 1
|
||||
dp[i][j] =
|
||||
(min(
|
||||
min(dp[i][j - 1].toDouble(), dp[i - 1][j].toDouble()),
|
||||
dp[i - 1][j - 1].toDouble()
|
||||
) + 1).toInt()
|
||||
dp[i][j] = min(min(dp[i][j - 1], dp[i - 1][j]), dp[i - 1][j - 1]) + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -112,7 +107,7 @@ fun editDistanceDPComp(s: String, t: String): Int {
|
||||
dp[j] = leftup
|
||||
} else {
|
||||
// 最少编辑步数 = 插入、删除、替换这三种操作的最少编辑步数 + 1
|
||||
dp[j] = (min(min(dp[j - 1].toDouble(), dp[j].toDouble()), leftup.toDouble()) + 1).toInt()
|
||||
dp[j] = min(min(dp[j - 1], dp[j]), leftup) + 1
|
||||
}
|
||||
leftup = temp // 更新为下一轮的 dp[i-1, j-1]
|
||||
}
|
||||
@@ -133,7 +128,8 @@ fun main() {
|
||||
|
||||
// 记忆化搜索
|
||||
val mem = Array(n + 1) { IntArray(m + 1) }
|
||||
for (row in mem) Arrays.fill(row, -1)
|
||||
for (row in mem)
|
||||
row.fill(-1)
|
||||
res = editDistanceDFSMem(s, t, mem, n, m)
|
||||
println("将 $s 更改为 $t 最少需要编辑 $res 步")
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
package chapter_dynamic_programming
|
||||
|
||||
import java.util.*
|
||||
import kotlin.math.max
|
||||
|
||||
/* 0-1 背包:暴力搜索 */
|
||||
@@ -28,7 +27,7 @@ fun knapsackDFS(
|
||||
val no = knapsackDFS(wgt, value, i - 1, c)
|
||||
val yes = knapsackDFS(wgt, value, i - 1, c - wgt[i - 1]) + value[i - 1]
|
||||
// 返回两种方案中价值更大的那一个
|
||||
return max(no.toDouble(), yes.toDouble()).toInt()
|
||||
return max(no, yes)
|
||||
}
|
||||
|
||||
/* 0-1 背包:记忆化搜索 */
|
||||
@@ -55,7 +54,7 @@ fun knapsackDFSMem(
|
||||
val no = knapsackDFSMem(wgt, value, mem, i - 1, c)
|
||||
val yes = knapsackDFSMem(wgt, value, mem, i - 1, c - wgt[i - 1]) + value[i - 1]
|
||||
// 记录并返回两种方案中价值更大的那一个
|
||||
mem[i][c] = max(no.toDouble(), yes.toDouble()).toInt()
|
||||
mem[i][c] = max(no, yes)
|
||||
return mem[i][c]
|
||||
}
|
||||
|
||||
@@ -76,8 +75,7 @@ fun knapsackDP(
|
||||
dp[i][c] = dp[i - 1][c]
|
||||
} else {
|
||||
// 不选和选物品 i 这两种方案的较大值
|
||||
dp[i][c] = max(dp[i - 1][c].toDouble(), (dp[i - 1][c - wgt[i - 1]] + value[i - 1]).toDouble())
|
||||
.toInt()
|
||||
dp[i][c] = max(dp[i - 1][c], dp[i - 1][c - wgt[i - 1]] + value[i - 1])
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -100,7 +98,7 @@ fun knapsackDPComp(
|
||||
if (wgt[i - 1] <= c) {
|
||||
// 不选和选物品 i 这两种方案的较大值
|
||||
dp[c] =
|
||||
max(dp[c].toDouble(), (dp[c - wgt[i - 1]] + value[i - 1]).toDouble()).toInt()
|
||||
max(dp[c], dp[c - wgt[i - 1]] + value[i - 1])
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -121,7 +119,7 @@ fun main() {
|
||||
// 记忆化搜索
|
||||
val mem = Array(n + 1) { IntArray(cap + 1) }
|
||||
for (row in mem) {
|
||||
Arrays.fill(row, -1)
|
||||
row.fill(-1)
|
||||
}
|
||||
res = knapsackDFSMem(wgt, value, mem, n, cap)
|
||||
println("不超过背包容量的最大物品价值为 $res")
|
||||
|
||||
@@ -19,7 +19,7 @@ fun minCostClimbingStairsDP(cost: IntArray): Int {
|
||||
dp[2] = cost[2]
|
||||
// 状态转移:从较小子问题逐步求解较大子问题
|
||||
for (i in 3..n) {
|
||||
dp[i] = (min(dp[i - 1].toDouble(), dp[i - 2].toDouble()) + cost[i]).toInt()
|
||||
dp[i] = min(dp[i - 1], dp[i - 2]) + cost[i]
|
||||
}
|
||||
return dp[n]
|
||||
}
|
||||
@@ -32,7 +32,7 @@ fun minCostClimbingStairsDPComp(cost: IntArray): Int {
|
||||
var b = cost[2]
|
||||
for (i in 3..n) {
|
||||
val tmp = b
|
||||
b = (min(a.toDouble(), tmp.toDouble()) + cost[i]).toInt()
|
||||
b = min(a, tmp) + cost[i]
|
||||
a = tmp
|
||||
}
|
||||
return b
|
||||
|
||||
@@ -6,15 +6,10 @@
|
||||
|
||||
package chapter_dynamic_programming
|
||||
|
||||
import java.util.*
|
||||
import kotlin.math.min
|
||||
|
||||
/* 最小路径和:暴力搜索 */
|
||||
fun minPathSumDFS(
|
||||
grid: Array<Array<Int>>,
|
||||
i: Int,
|
||||
j: Int
|
||||
): Int {
|
||||
fun minPathSumDFS(grid: Array<IntArray>, i: Int, j: Int): Int {
|
||||
// 若为左上角单元格,则终止搜索
|
||||
if (i == 0 && j == 0) {
|
||||
return grid[0][0]
|
||||
@@ -27,13 +22,13 @@ fun minPathSumDFS(
|
||||
val up = minPathSumDFS(grid, i - 1, j)
|
||||
val left = minPathSumDFS(grid, i, j - 1)
|
||||
// 返回从左上角到 (i, j) 的最小路径代价
|
||||
return (min(left.toDouble(), up.toDouble()) + grid[i][j]).toInt()
|
||||
return min(left, up) + grid[i][j]
|
||||
}
|
||||
|
||||
/* 最小路径和:记忆化搜索 */
|
||||
fun minPathSumDFSMem(
|
||||
grid: Array<Array<Int>>,
|
||||
mem: Array<Array<Int>>,
|
||||
grid: Array<IntArray>,
|
||||
mem: Array<IntArray>,
|
||||
i: Int,
|
||||
j: Int
|
||||
): Int {
|
||||
@@ -53,12 +48,12 @@ fun minPathSumDFSMem(
|
||||
val up = minPathSumDFSMem(grid, mem, i - 1, j)
|
||||
val left = minPathSumDFSMem(grid, mem, i, j - 1)
|
||||
// 记录并返回左上角到 (i, j) 的最小路径代价
|
||||
mem[i][j] = (min(left.toDouble(), up.toDouble()) + grid[i][j]).toInt()
|
||||
mem[i][j] = min(left, up) + grid[i][j]
|
||||
return mem[i][j]
|
||||
}
|
||||
|
||||
/* 最小路径和:动态规划 */
|
||||
fun minPathSumDP(grid: Array<Array<Int>>): Int {
|
||||
fun minPathSumDP(grid: Array<IntArray>): Int {
|
||||
val n = grid.size
|
||||
val m = grid[0].size
|
||||
// 初始化 dp 表
|
||||
@@ -75,15 +70,14 @@ fun minPathSumDP(grid: Array<Array<Int>>): Int {
|
||||
// 状态转移:其余行和列
|
||||
for (i in 1..<n) {
|
||||
for (j in 1..<m) {
|
||||
dp[i][j] =
|
||||
(min(dp[i][j - 1].toDouble(), dp[i - 1][j].toDouble()) + grid[i][j]).toInt()
|
||||
dp[i][j] = min(dp[i][j - 1], dp[i - 1][j]) + grid[i][j]
|
||||
}
|
||||
}
|
||||
return dp[n - 1][m - 1]
|
||||
}
|
||||
|
||||
/* 最小路径和:空间优化后的动态规划 */
|
||||
fun minPathSumDPComp(grid: Array<Array<Int>>): Int {
|
||||
fun minPathSumDPComp(grid: Array<IntArray>): Int {
|
||||
val n = grid.size
|
||||
val m = grid[0].size
|
||||
// 初始化 dp 表
|
||||
@@ -99,7 +93,7 @@ fun minPathSumDPComp(grid: Array<Array<Int>>): Int {
|
||||
dp[0] = dp[0] + grid[i][0]
|
||||
// 状态转移:其余列
|
||||
for (j in 1..<m) {
|
||||
dp[j] = (min(dp[j - 1].toDouble(), dp[j].toDouble()) + grid[i][j]).toInt()
|
||||
dp[j] = min(dp[j - 1], dp[j]) + grid[i][j]
|
||||
}
|
||||
}
|
||||
return dp[m - 1]
|
||||
@@ -108,10 +102,10 @@ fun minPathSumDPComp(grid: Array<Array<Int>>): Int {
|
||||
/* Driver Code */
|
||||
fun main() {
|
||||
val grid = arrayOf(
|
||||
arrayOf(1, 3, 1, 5),
|
||||
arrayOf(2, 2, 4, 2),
|
||||
arrayOf(5, 3, 2, 1),
|
||||
arrayOf(4, 3, 5, 2)
|
||||
intArrayOf(1, 3, 1, 5),
|
||||
intArrayOf(2, 2, 4, 2),
|
||||
intArrayOf(5, 3, 2, 1),
|
||||
intArrayOf(4, 3, 5, 2)
|
||||
)
|
||||
val n = grid.size
|
||||
val m = grid[0].size
|
||||
@@ -121,9 +115,9 @@ fun main() {
|
||||
println("从左上角到右下角的最小路径和为 $res")
|
||||
|
||||
// 记忆化搜索
|
||||
val mem = Array(n) { Array(m) { 0 } }
|
||||
val mem = Array(n) { IntArray(m) }
|
||||
for (row in mem) {
|
||||
Arrays.fill(row, -1)
|
||||
row.fill(-1)
|
||||
}
|
||||
res = minPathSumDFSMem(grid, mem, n - 1, m - 1)
|
||||
println("从左上角到右下角的最小路径和为 $res")
|
||||
|
||||
@@ -9,11 +9,7 @@ package chapter_dynamic_programming
|
||||
import kotlin.math.max
|
||||
|
||||
/* 完全背包:动态规划 */
|
||||
fun unboundedKnapsackDP(
|
||||
wgt: IntArray,
|
||||
value: IntArray,
|
||||
cap: Int
|
||||
): Int {
|
||||
fun unboundedKnapsackDP(wgt: IntArray, value: IntArray, cap: Int): Int {
|
||||
val n = wgt.size
|
||||
// 初始化 dp 表
|
||||
val dp = Array(n + 1) { IntArray(cap + 1) }
|
||||
@@ -25,8 +21,7 @@ fun unboundedKnapsackDP(
|
||||
dp[i][c] = dp[i - 1][c]
|
||||
} else {
|
||||
// 不选和选物品 i 这两种方案的较大值
|
||||
dp[i][c] = max(dp[i - 1][c].toDouble(), (dp[i][c - wgt[i - 1]] + value[i - 1]).toDouble())
|
||||
.toInt()
|
||||
dp[i][c] = max(dp[i - 1][c], dp[i][c - wgt[i - 1]] + value[i - 1])
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -50,8 +45,7 @@ fun unboundedKnapsackDPComp(
|
||||
dp[c] = dp[c]
|
||||
} else {
|
||||
// 不选和选物品 i 这两种方案的较大值
|
||||
dp[c] =
|
||||
max(dp[c].toDouble(), (dp[c - wgt[i - 1]] + value[i - 1]).toDouble()).toInt()
|
||||
dp[c] = max(dp[c], dp[c - wgt[i - 1]] + value[i - 1])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user