This commit is contained in:
krahets
2024-04-13 21:17:44 +08:00
parent 9332a91e26
commit 6afa70e7bc
55 changed files with 334 additions and 182 deletions
@@ -760,6 +760,7 @@ It's important to note that even though node `P` continues to point to `n1` afte
fun remove(n0: ListNode?) {
if (n0?.next == null)
return
// n0 -> P -> n1
val p = n0.next
val n1 = p?.next
n0.next = n1
@@ -1992,6 +1992,7 @@ Therefore, **we can use an explicit stack to simulate the behavior of the call s
var res = 0
// 递: 递归调用
for (i in n downTo 0) {
// 通过“入栈操作”模拟“递”
stack.push(i)
}
// 归: 返回结果
@@ -1319,7 +1319,6 @@ Linear order indicates the number of operations grows linearly with the input da
/* 线性阶 */
fun linear(n: Int): Int {
var count = 0
// 循环次数与数组长度成正比
for (i in 0..<n)
count++
return count
@@ -2063,7 +2062,9 @@ For instance, in bubble sort, the outer loop runs $n - 1$ times, and the inner l
for (j in 0..<i) {
if (nums[j] > nums[j + 1]) {
// 交换 nums[j] 与 nums[j + 1]
nums[j] = nums[j + 1].also { nums[j + 1] = nums[j] }
val temp = nums[j]
nums[j] = nums[j + 1]
nums[j + 1] = temp
count += 3 // 元素交换包含 3 个单元操作
}
}
@@ -2340,8 +2341,8 @@ The following image and code simulate the cell division process, with a time com
/* 指数阶(循环实现) */
fun exponential(n: Int): Int {
var count = 0
// 细胞每轮一分为二,形成数列 1, 2, 4, 8, ..., 2^(n-1)
var base = 1
// 细胞每轮一分为二,形成数列 1, 2, 4, 8, ..., 2^(n-1)
for (i in 0..<n) {
for (j in 0..<base) {
count++
@@ -3747,12 +3748,11 @@ The "worst-case time complexity" corresponds to the asymptotic upper bound, deno
for (i in 0..<n) {
nums[i] = i + 1
}
val mutableList = nums.toMutableList()
// 随机打乱数组元素
mutableList.shuffle()
nums.shuffle()
val res = arrayOfNulls<Int>(n)
for (i in 0..<n) {
res[i] = mutableList[i]
res[i] = nums[i]
}
return res
}
+13 -13
View File
@@ -1103,8 +1103,8 @@ Below is the implementation code for graphs represented using an adjacency matri
if (i < 0 || j < 0 || i >= size() || j >= size() || i == j)
throw IndexOutOfBoundsException()
// 在无向图中,邻接矩阵关于主对角线对称,即满足 (i, j) == (j, i)
adjMat[i][j] = 1;
adjMat[j][i] = 1;
adjMat[i][j] = 1
adjMat[j][i] = 1
}
/* 删除边 */
@@ -1113,15 +1113,15 @@ Below is the implementation code for graphs represented using an adjacency matri
// 索引越界与相等处理
if (i < 0 || j < 0 || i >= size() || j >= size() || i == j)
throw IndexOutOfBoundsException()
adjMat[i][j] = 0;
adjMat[j][i] = 0;
adjMat[i][j] = 0
adjMat[j][i] = 0
}
/* 打印邻接矩阵 */
fun print() {
print("顶点列表 = ")
println(vertices);
println("邻接矩阵 =");
println(vertices)
println("邻接矩阵 =")
printMatrix(adjMat)
}
}
@@ -2167,9 +2167,9 @@ Additionally, we use the `Vertex` class to represent vertices in the adjacency l
init {
// 添加所有顶点和边
for (edge in edges) {
addVertex(edge[0]!!);
addVertex(edge[1]!!);
addEdge(edge[0]!!, edge[1]!!);
addVertex(edge[0]!!)
addVertex(edge[1]!!)
addEdge(edge[0]!!, edge[1]!!)
}
}
@@ -2184,7 +2184,7 @@ Additionally, we use the `Vertex` class to represent vertices in the adjacency l
throw IllegalArgumentException()
// 添加边 vet1 - vet2
adjList[vet1]?.add(vet2)
adjList[vet2]?.add(vet1);
adjList[vet2]?.add(vet1)
}
/* 删除边 */
@@ -2192,8 +2192,8 @@ Additionally, we use the `Vertex` class to represent vertices in the adjacency l
if (!adjList.containsKey(vet1) || !adjList.containsKey(vet2) || vet1 == vet2)
throw IllegalArgumentException()
// 删除边 vet1 - vet2
adjList[vet1]?.remove(vet2);
adjList[vet2]?.remove(vet1);
adjList[vet1]?.remove(vet2)
adjList[vet2]?.remove(vet1)
}
/* 添加顶点 */
@@ -2209,7 +2209,7 @@ Additionally, we use the `Vertex` class to represent vertices in the adjacency l
if (!adjList.containsKey(vet))
throw IllegalArgumentException()
// 在邻接表中删除顶点 vet 对应的链表
adjList.remove(vet);
adjList.remove(vet)
// 遍历其他顶点的链表,删除所有包含 vet 的边
for (list in adjList.values) {
list.remove(vet)
@@ -560,6 +560,7 @@ The design of hash algorithms is a complex issue that requires consideration of
/* 加法哈希 */
fun addHash(key: String): Int {
var hash = 0L
val MODULUS = 1000000007
for (c in key.toCharArray()) {
hash = (hash + c.code) % MODULUS
}
@@ -569,6 +570,7 @@ The design of hash algorithms is a complex issue that requires consideration of
/* 乘法哈希 */
fun mulHash(key: String): Int {
var hash = 0L
val MODULUS = 1000000007
for (c in key.toCharArray()) {
hash = (31 * hash + c.code) % MODULUS
}
@@ -578,6 +580,7 @@ The design of hash algorithms is a complex issue that requires consideration of
/* 异或哈希 */
fun xorHash(key: String): Int {
var hash = 0
val MODULUS = 1000000007
for (c in key.toCharArray()) {
hash = hash xor c.code
}
@@ -587,6 +590,7 @@ The design of hash algorithms is a complex issue that requires consideration of
/* 旋转哈希 */
fun rotHash(key: String): Int {
var hash = 0L
val MODULUS = 1000000007
for (c in key.toCharArray()) {
hash = ((hash shl 4) xor (hash shr 28) xor c.code.toLong()) % MODULUS
}
+1 -1
View File
@@ -1312,7 +1312,7 @@ The code below provides a simple implementation of a separate chaining hash tabl
```kotlin title="hash_map_chaining.kt"
/* 链式地址哈希表 */
class HashMapChaining() {
class HashMapChaining {
var size: Int // 键值对数量
var capacity: Int // 哈希表容量
val loadThres: Double // 触发扩容的负载因子阈值
+3 -2
View File
@@ -1605,7 +1605,8 @@ The following code implements a simple hash table. Here, we encapsulate `key` an
fun valueSet(): MutableList<String> {
val valueSet = mutableListOf<String>()
for (pair in buckets) {
pair?.let { valueSet.add(it._val) }
if (pair != null)
valueSet.add(pair._val)
}
return valueSet
}
@@ -1615,7 +1616,7 @@ The following code implements a simple hash table. Here, we encapsulate `key` an
for (kv in pairSet()) {
val key = kv.key
val _val = kv._val
println("${key} -> ${_val}")
println("$key -> $_val")
}
}
}
+3 -1
View File
@@ -220,7 +220,9 @@ It's worth mentioning that **since leaf nodes have no children, they naturally f
/* 交换元素 */
private fun swap(i: Int, j: Int) {
maxHeap[i] = maxHeap[j].also { maxHeap[j] = maxHeap[i] }
val temp = maxHeap[i]
maxHeap[i] = maxHeap[j]
maxHeap[j] = temp
}
/* 获取堆大小 */
+1 -1
View File
@@ -649,7 +649,7 @@ We can encapsulate the index mapping formula into functions for convenient later
/* 获取父节点的索引 */
int parent(MaxHeap *maxHeap, int i) {
return (i - 1) / 2;
return (i - 1) / 2; // 向下取整
}
```
+1 -1
View File
@@ -1045,7 +1045,7 @@ Below is an example code for implementing a stack based on a linked list:
fun pop(): Int? {
val num = peek()
stackPeek = stackPeek?.next
stkSize--;
stkSize--
return num
}
@@ -1172,7 +1172,7 @@ The following code implements a binary tree based on array representation, inclu
=== "Kotlin"
```kotlin title="array_binary_tree.kt"
/* 构造方法 */
/* 数组表示下的二叉树类 */
class ArrayBinaryTree(val tree: MutableList<Int?>) {
/* 列表容量 */
fun size(): Int {
@@ -305,7 +305,7 @@ Breadth-first traversal is usually implemented with the help of a "queue". The q
val list = mutableListOf<Int>()
while (queue.isNotEmpty()) {
val node = queue.poll() // 队列出队
list.add(node?._val!!) // 保存节点值
list.add(node?._val!!) // 保存节点值
if (node.left != null)
queue.offer(node.left) // 左子节点入队
if (node.right != null)