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

Improve readability of kotlin code #1233

Merged
merged 2 commits into from
Apr 7, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Next Next commit
style(kotlin): Improve kotlin codes readability.
  • Loading branch information
curtishd committed Apr 7, 2024
commit 3fcef70b3c83e589e1503bcc06da33260f498f5f
14 changes: 10 additions & 4 deletions codes/kotlin/chapter_divide_and_conquer/build_tree.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,13 @@ import utils.TreeNode
import utils.printTree

/* 构建二叉树:分治 */
fun dfs(preorder: IntArray, inorderMap: Map<Int?, Int?>, i: Int, l: Int, r: Int): TreeNode? {
fun dfs(
preorder: IntArray,
inorderMap: Map<Int?, Int?>,
i: Int,
l: Int,
r: Int
): TreeNode? {
// 子树区间为空时终止
if (r - l < 0) return null
// 初始化根节点
Expand All @@ -28,7 +34,7 @@ fun dfs(preorder: IntArray, inorderMap: Map<Int?, Int?>, i: Int, l: Int, r: Int)
/* 构建二叉树 */
fun buildTree(preorder: IntArray, inorder: IntArray): TreeNode? {
// 初始化哈希表,存储 inorder 元素到索引的映射
val inorderMap: MutableMap<Int?, Int?> = HashMap()
val inorderMap = HashMap<Int?, Int?>()
for (i in inorder.indices) {
inorderMap[inorder[i]] = i
}
Expand All @@ -40,8 +46,8 @@ fun buildTree(preorder: IntArray, inorder: IntArray): TreeNode? {
fun main() {
val preorder = intArrayOf(3, 9, 2, 1, 7)
val inorder = intArrayOf(9, 3, 1, 2, 7)
println("前序遍历 = " + preorder.contentToString())
println("中序遍历 = " + inorder.contentToString())
println("前序遍历 = ${preorder.contentToString()}")
println("中序遍历 = ${inorder.contentToString()}")

val root = buildTree(preorder, inorder)
println("构建的二叉树为:")
Expand Down
10 changes: 5 additions & 5 deletions codes/kotlin/chapter_divide_and_conquer/hanota.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ package chapter_divide_and_conquer.hanota
/* 移动一个圆盘 */
fun move(src: MutableList<Int>, tar: MutableList<Int>) {
// 从 src 顶部拿出一个圆盘
val pan: Int = src.removeAt(src.size - 1)
val pan = src.removeAt(src.size - 1)
// 将圆盘放入 tar 顶部
tar.add(pan)
}
Expand Down Expand Up @@ -39,9 +39,9 @@ fun solveHanota(A: MutableList<Int>, B: MutableList<Int>, C: MutableList<Int>) {
/* Driver Code */
fun main() {
// 列表尾部是柱子顶部
val A: MutableList<Int> = ArrayList(mutableListOf(5, 4, 3, 2, 1))
val B: MutableList<Int> = ArrayList()
val C: MutableList<Int> = ArrayList()
val A = mutableListOf(5, 4, 3, 2, 1)
val B = mutableListOf<Int>()
val C = mutableListOf<Int>()
println("初始状态下:")
println("A = $A")
println("B = $B")
Expand All @@ -53,4 +53,4 @@ fun main() {
println("A = $A")
println("B = $B")
println("C = $C")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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 阶
Expand All @@ -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]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@

package chapter_dynamic_programming

import java.util.*

/* 记忆化搜索 */
fun dfs(i: Int, mem: IntArray): Int {
// 已知 dp[1] 和 dp[2] ,返回之
Expand All @@ -25,14 +23,14 @@ 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)
}

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

val res: Int = climbingStairsDFSMem(n)
val res = climbingStairsDFSMem(n)
println("爬 $n 阶楼梯共有 $res 种方案")
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
8 changes: 3 additions & 5 deletions codes/kotlin/chapter_dynamic_programming/coin_change.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

package chapter_dynamic_programming

import java.util.*
import kotlin.math.min

/* 零钱兑换:动态规划 */
Expand All @@ -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))
}
}
}
Expand All @@ -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) {
Expand All @@ -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))
}
}
}
Expand Down
16 changes: 6 additions & 10 deletions codes/kotlin/chapter_dynamic_programming/edit_distance.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

package chapter_dynamic_programming

import java.util.*
import kotlin.math.min

/* 编辑距离:暴力搜索 */
Expand All @@ -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
}

/* 编辑距离:记忆化搜索 */
Expand All @@ -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]
}

Expand All @@ -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
}
}
}
Expand Down Expand Up @@ -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]
}
Expand All @@ -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 步")

Expand Down
12 changes: 5 additions & 7 deletions codes/kotlin/chapter_dynamic_programming/knapsack.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

package chapter_dynamic_programming

import java.util.*
import kotlin.math.max

/* 0-1 背包:暴力搜索 */
Expand All @@ -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 背包:记忆化搜索 */
Expand All @@ -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]
}

Expand All @@ -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])
}
}
}
Expand All @@ -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])
}
}
}
Expand All @@ -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")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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]
}
Expand All @@ -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
Expand Down
36 changes: 15 additions & 21 deletions codes/kotlin/chapter_dynamic_programming/min_path_sum.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand All @@ -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 {
Expand All @@ -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 表
Expand All @@ -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 表
Expand All @@ -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]
Expand All @@ -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
Expand All @@ -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")
Expand Down
Loading