mirror of
https://github.com/krahets/hello-algo.git
synced 2025-07-27 04:12:40 +08:00
build
This commit is contained in:
@ -813,6 +813,7 @@ comments: true
|
||||
fun remove(n0: ListNode?) {
|
||||
if (n0?.next == null)
|
||||
return
|
||||
// n0 -> P -> n1
|
||||
val p = n0.next
|
||||
val n1 = p?.next
|
||||
n0.next = n1
|
||||
|
@ -385,10 +385,10 @@ comments: true
|
||||
nums.Add(4);
|
||||
|
||||
/* 在中间插入元素 */
|
||||
nums.Insert(3, 6);
|
||||
nums.Insert(3, 6); // 在索引 3 处插入数字 6
|
||||
|
||||
/* 删除元素 */
|
||||
nums.RemoveAt(3);
|
||||
nums.RemoveAt(3); // 删除索引 3 处的元素
|
||||
```
|
||||
|
||||
=== "Go"
|
||||
@ -445,10 +445,10 @@ comments: true
|
||||
nums.push(4);
|
||||
|
||||
/* 在中间插入元素 */
|
||||
nums.splice(3, 0, 6);
|
||||
nums.splice(3, 0, 6); // 在索引 3 处插入数字 6
|
||||
|
||||
/* 删除元素 */
|
||||
nums.splice(3, 1);
|
||||
nums.splice(3, 1); // 删除索引 3 处的元素
|
||||
```
|
||||
|
||||
=== "TS"
|
||||
@ -465,10 +465,10 @@ comments: true
|
||||
nums.push(4);
|
||||
|
||||
/* 在中间插入元素 */
|
||||
nums.splice(3, 0, 6);
|
||||
nums.splice(3, 0, 6); // 在索引 3 处插入数字 6
|
||||
|
||||
/* 删除元素 */
|
||||
nums.splice(3, 1);
|
||||
nums.splice(3, 1); // 删除索引 3 处的元素
|
||||
```
|
||||
|
||||
=== "Dart"
|
||||
|
@ -1992,6 +1992,7 @@ comments: true
|
||||
var res = 0
|
||||
// 递: 递归调用
|
||||
for (i in n downTo 0) {
|
||||
// 通过“入栈操作”模拟“递”
|
||||
stack.push(i)
|
||||
}
|
||||
// 归: 返回结果
|
||||
|
@ -1431,7 +1431,6 @@ $$
|
||||
/* 线性阶 */
|
||||
fun linear(n: Int): Int {
|
||||
var count = 0
|
||||
// 循环次数与数组长度成正比
|
||||
for (i in 0..<n)
|
||||
count++
|
||||
return count
|
||||
@ -2175,7 +2174,9 @@ $$
|
||||
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 个单元操作
|
||||
}
|
||||
}
|
||||
@ -2452,8 +2453,8 @@ $$
|
||||
/* 指数阶(循环实现) */
|
||||
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++
|
||||
@ -3859,12 +3860,11 @@ $$
|
||||
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
|
||||
}
|
||||
|
@ -184,7 +184,9 @@ comments: true
|
||||
if state + choice > n {
|
||||
continue
|
||||
}
|
||||
// 尝试:做出选择,更新状态
|
||||
backtrack(choices: choices, state: state + choice, n: n, res: &res)
|
||||
// 回退
|
||||
}
|
||||
}
|
||||
|
||||
@ -1597,7 +1599,9 @@ $$
|
||||
var a = 1
|
||||
var b = 2
|
||||
for (i in 3..n) {
|
||||
b += a.also { a = b }
|
||||
val temp = b
|
||||
b += a
|
||||
a = temp
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
@ -1036,11 +1036,7 @@ $$
|
||||
|
||||
```kotlin title="knapsack.kt"
|
||||
/* 0-1 背包:动态规划 */
|
||||
fun knapsackDP(
|
||||
wgt: IntArray,
|
||||
_val: IntArray,
|
||||
cap: Int
|
||||
): Int {
|
||||
fun knapsackDP(wgt: IntArray, _val: IntArray, cap: Int): Int {
|
||||
val n = wgt.size
|
||||
// 初始化 dp 表
|
||||
val dp = Array(n + 1) { IntArray(cap + 1) }
|
||||
@ -1429,11 +1425,7 @@ $$
|
||||
|
||||
```kotlin title="knapsack.kt"
|
||||
/* 0-1 背包:空间优化后的动态规划 */
|
||||
fun knapsackDPComp(
|
||||
wgt: IntArray,
|
||||
_val: IntArray,
|
||||
cap: Int
|
||||
): Int {
|
||||
fun knapsackDPComp(wgt: IntArray, _val: IntArray, cap: Int): Int {
|
||||
val n = wgt.size
|
||||
// 初始化 dp 表
|
||||
val dp = IntArray(cap + 1)
|
||||
@ -1443,8 +1435,7 @@ $$
|
||||
for (c in cap downTo 1) {
|
||||
if (wgt[i - 1] <= c) {
|
||||
// 不选和选物品 i 这两种方案的较大值
|
||||
dp[c] =
|
||||
max(dp[c], dp[c - wgt[i - 1]] + _val[i - 1])
|
||||
dp[c] = max(dp[c], dp[c - wgt[i - 1]] + _val[i - 1])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1103,8 +1103,8 @@ comments: true
|
||||
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 @@ comments: true
|
||||
// 索引越界与相等处理
|
||||
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 @@ comments: true
|
||||
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 @@ comments: true
|
||||
throw IllegalArgumentException()
|
||||
// 添加边 vet1 - vet2
|
||||
adjList[vet1]?.add(vet2)
|
||||
adjList[vet2]?.add(vet1);
|
||||
adjList[vet2]?.add(vet1)
|
||||
}
|
||||
|
||||
/* 删除边 */
|
||||
@ -2192,8 +2192,8 @@ comments: true
|
||||
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 @@ comments: true
|
||||
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 @@ index = hash(key) % capacity
|
||||
/* 加法哈希 */
|
||||
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 @@ index = hash(key) % capacity
|
||||
/* 乘法哈希 */
|
||||
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 @@ index = hash(key) % capacity
|
||||
/* 异或哈希 */
|
||||
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 @@ index = hash(key) % capacity
|
||||
/* 旋转哈希 */
|
||||
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
|
||||
}
|
||||
|
@ -1312,7 +1312,7 @@ comments: true
|
||||
|
||||
```kotlin title="hash_map_chaining.kt"
|
||||
/* 链式地址哈希表 */
|
||||
class HashMapChaining() {
|
||||
class HashMapChaining {
|
||||
var size: Int // 键值对数量
|
||||
var capacity: Int // 哈希表容量
|
||||
val loadThres: Double // 触发扩容的负载因子阈值
|
||||
|
@ -1646,7 +1646,8 @@ index = hash(key) % capacity
|
||||
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
|
||||
}
|
||||
@ -1656,7 +1657,7 @@ index = hash(key) % capacity
|
||||
for (kv in pairSet()) {
|
||||
val key = kv.key
|
||||
val _val = kv._val
|
||||
println("${key} -> ${_val}")
|
||||
println("$key -> $_val")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -220,7 +220,9 @@ comments: true
|
||||
|
||||
/* 交换元素 */
|
||||
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
|
||||
}
|
||||
|
||||
/* 获取堆大小 */
|
||||
|
@ -650,7 +650,7 @@ comments: true
|
||||
|
||||
/* 获取父节点的索引 */
|
||||
int parent(MaxHeap *maxHeap, int i) {
|
||||
return (i - 1) / 2;
|
||||
return (i - 1) / 2; // 向下取整
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -264,7 +264,9 @@ comments: true
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -571,7 +573,9 @@ comments: true
|
||||
for (j in 0..<i) {
|
||||
if (nums[j] > nums[j + 1]) {
|
||||
// 交换 nums[j] 与 nums[j + 1]
|
||||
nums[j] = nums[j + 1].also { nums[j] = nums[j + 1] }
|
||||
val temp = nums[j]
|
||||
nums[j] = nums[j + 1]
|
||||
nums[j + 1] = temp
|
||||
flag = true // 记录交换元素
|
||||
}
|
||||
}
|
||||
|
@ -553,7 +553,9 @@ comments: true
|
||||
if (ma == i)
|
||||
break
|
||||
// 交换两节点
|
||||
nums[i] = nums[ma].also { nums[ma] = nums[i] }
|
||||
val temp = nums[i]
|
||||
nums[i] = nums[ma]
|
||||
nums[ma] = temp
|
||||
// 循环向下堆化
|
||||
i = ma
|
||||
}
|
||||
@ -568,7 +570,9 @@ comments: true
|
||||
// 从堆中提取最大元素,循环 n-1 轮
|
||||
for (i in nums.size - 1 downTo 1) {
|
||||
// 交换根节点与最右叶节点(交换首元素与尾元素)
|
||||
nums[0] = nums[i].also { nums[i] = nums[0] }
|
||||
val temp = nums[0]
|
||||
nums[0] = nums[i]
|
||||
nums[i] = temp
|
||||
// 以根节点为起点,从顶至底进行堆化
|
||||
siftDown(nums, i, 0)
|
||||
}
|
||||
|
@ -328,7 +328,9 @@ comments: true
|
||||
```kotlin title="quick_sort.kt"
|
||||
/* 元素交换 */
|
||||
fun swap(nums: IntArray, i: Int, j: Int) {
|
||||
nums[i] = nums[j].also { nums[j] = nums[i] }
|
||||
val temp = nums[i]
|
||||
nums[i] = nums[j]
|
||||
nums[j] = temp
|
||||
}
|
||||
|
||||
/* 哨兵划分 */
|
||||
|
@ -296,7 +296,9 @@ comments: true
|
||||
k = j // 记录最小元素的索引
|
||||
}
|
||||
// 将该最小元素与未排序区间的首个元素交换
|
||||
nums[i] = nums[k].also { nums[k] = nums[i] }
|
||||
val temp = nums[i]
|
||||
nums[i] = nums[k]
|
||||
nums[k] = temp
|
||||
}
|
||||
}
|
||||
```
|
||||
|
@ -1092,7 +1092,7 @@ comments: true
|
||||
fun pop(): Int? {
|
||||
val num = peek()
|
||||
stackPeek = stackPeek?.next
|
||||
stkSize--;
|
||||
stkSize--
|
||||
return num
|
||||
}
|
||||
|
||||
|
@ -125,7 +125,7 @@ comments: true
|
||||
```kotlin title=""
|
||||
/* 二叉树的数组表示 */
|
||||
// 使用 null 来表示空位
|
||||
val tree = mutableListOf( 1, 2, 3, 4, null, 6, 7, 8, 9, null, null, 12, null, null, 15 )
|
||||
val tree = arrayOf( 1, 2, 3, 4, null, 6, 7, 8, 9, null, null, 12, null, null, 15 )
|
||||
```
|
||||
|
||||
=== "Ruby"
|
||||
@ -1172,7 +1172,7 @@ comments: true
|
||||
=== "Kotlin"
|
||||
|
||||
```kotlin title="array_binary_tree.kt"
|
||||
/* 构造方法 */
|
||||
/* 数组表示下的二叉树类 */
|
||||
class ArrayBinaryTree(val tree: MutableList<Int?>) {
|
||||
/* 列表容量 */
|
||||
fun size(): Int {
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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 // 触发扩容的负载因子阈值
|
||||
|
@ -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")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
/* 获取堆大小 */
|
||||
|
@ -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; // 向下取整
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -813,6 +813,7 @@ comments: true
|
||||
fun remove(n0: ListNode?) {
|
||||
if (n0?.next == null)
|
||||
return
|
||||
// n0 -> P -> n1
|
||||
val p = n0.next
|
||||
val n1 = p?.next
|
||||
n0.next = n1
|
||||
|
@ -385,10 +385,10 @@ comments: true
|
||||
nums.Add(4);
|
||||
|
||||
/* 在中間插入元素 */
|
||||
nums.Insert(3, 6);
|
||||
nums.Insert(3, 6); // 在索引 3 處插入數字 6
|
||||
|
||||
/* 刪除元素 */
|
||||
nums.RemoveAt(3);
|
||||
nums.RemoveAt(3); // 刪除索引 3 處的元素
|
||||
```
|
||||
|
||||
=== "Go"
|
||||
@ -445,10 +445,10 @@ comments: true
|
||||
nums.push(4);
|
||||
|
||||
/* 在中間插入元素 */
|
||||
nums.splice(3, 0, 6);
|
||||
nums.splice(3, 0, 6); // 在索引 3 處插入數字 6
|
||||
|
||||
/* 刪除元素 */
|
||||
nums.splice(3, 1);
|
||||
nums.splice(3, 1); // 刪除索引 3 處的元素
|
||||
```
|
||||
|
||||
=== "TS"
|
||||
@ -465,10 +465,10 @@ comments: true
|
||||
nums.push(4);
|
||||
|
||||
/* 在中間插入元素 */
|
||||
nums.splice(3, 0, 6);
|
||||
nums.splice(3, 0, 6); // 在索引 3 處插入數字 6
|
||||
|
||||
/* 刪除元素 */
|
||||
nums.splice(3, 1);
|
||||
nums.splice(3, 1); // 刪除索引 3 處的元素
|
||||
```
|
||||
|
||||
=== "Dart"
|
||||
|
@ -1992,6 +1992,7 @@ comments: true
|
||||
var res = 0
|
||||
// 遞: 遞迴呼叫
|
||||
for (i in n downTo 0) {
|
||||
// 透過“入堆疊操作”模擬“遞”
|
||||
stack.push(i)
|
||||
}
|
||||
// 迴: 返回結果
|
||||
|
@ -1431,7 +1431,6 @@ $$
|
||||
/* 線性階 */
|
||||
fun linear(n: Int): Int {
|
||||
var count = 0
|
||||
// 迴圈次數與陣列長度成正比
|
||||
for (i in 0..<n)
|
||||
count++
|
||||
return count
|
||||
@ -2175,7 +2174,9 @@ $$
|
||||
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 個單元操作
|
||||
}
|
||||
}
|
||||
@ -2452,8 +2453,8 @@ $$
|
||||
/* 指數階(迴圈實現) */
|
||||
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++
|
||||
@ -3859,12 +3860,11 @@ $$
|
||||
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
|
||||
}
|
||||
|
@ -184,7 +184,9 @@ comments: true
|
||||
if state + choice > n {
|
||||
continue
|
||||
}
|
||||
// 嘗試:做出選擇,更新狀態
|
||||
backtrack(choices: choices, state: state + choice, n: n, res: &res)
|
||||
// 回退
|
||||
}
|
||||
}
|
||||
|
||||
@ -1597,7 +1599,9 @@ $$
|
||||
var a = 1
|
||||
var b = 2
|
||||
for (i in 3..n) {
|
||||
b += a.also { a = b }
|
||||
val temp = b
|
||||
b += a
|
||||
a = temp
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
@ -1036,11 +1036,7 @@ $$
|
||||
|
||||
```kotlin title="knapsack.kt"
|
||||
/* 0-1 背包:動態規劃 */
|
||||
fun knapsackDP(
|
||||
wgt: IntArray,
|
||||
_val: IntArray,
|
||||
cap: Int
|
||||
): Int {
|
||||
fun knapsackDP(wgt: IntArray, _val: IntArray, cap: Int): Int {
|
||||
val n = wgt.size
|
||||
// 初始化 dp 表
|
||||
val dp = Array(n + 1) { IntArray(cap + 1) }
|
||||
@ -1429,11 +1425,7 @@ $$
|
||||
|
||||
```kotlin title="knapsack.kt"
|
||||
/* 0-1 背包:空間最佳化後的動態規劃 */
|
||||
fun knapsackDPComp(
|
||||
wgt: IntArray,
|
||||
_val: IntArray,
|
||||
cap: Int
|
||||
): Int {
|
||||
fun knapsackDPComp(wgt: IntArray, _val: IntArray, cap: Int): Int {
|
||||
val n = wgt.size
|
||||
// 初始化 dp 表
|
||||
val dp = IntArray(cap + 1)
|
||||
@ -1443,8 +1435,7 @@ $$
|
||||
for (c in cap downTo 1) {
|
||||
if (wgt[i - 1] <= c) {
|
||||
// 不選和選物品 i 這兩種方案的較大值
|
||||
dp[c] =
|
||||
max(dp[c], dp[c - wgt[i - 1]] + _val[i - 1])
|
||||
dp[c] = max(dp[c], dp[c - wgt[i - 1]] + _val[i - 1])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1103,8 +1103,8 @@ comments: true
|
||||
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 @@ comments: true
|
||||
// 索引越界與相等處理
|
||||
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 @@ comments: true
|
||||
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 @@ comments: true
|
||||
throw IllegalArgumentException()
|
||||
// 新增邊 vet1 - vet2
|
||||
adjList[vet1]?.add(vet2)
|
||||
adjList[vet2]?.add(vet1);
|
||||
adjList[vet2]?.add(vet1)
|
||||
}
|
||||
|
||||
/* 刪除邊 */
|
||||
@ -2192,8 +2192,8 @@ comments: true
|
||||
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 @@ comments: true
|
||||
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 @@ index = hash(key) % capacity
|
||||
/* 加法雜湊 */
|
||||
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 @@ index = hash(key) % capacity
|
||||
/* 乘法雜湊 */
|
||||
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 @@ index = hash(key) % capacity
|
||||
/* 互斥或雜湊 */
|
||||
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 @@ index = hash(key) % capacity
|
||||
/* 旋轉雜湊 */
|
||||
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
|
||||
}
|
||||
|
@ -1312,7 +1312,7 @@ comments: true
|
||||
|
||||
```kotlin title="hash_map_chaining.kt"
|
||||
/* 鏈式位址雜湊表 */
|
||||
class HashMapChaining() {
|
||||
class HashMapChaining {
|
||||
var size: Int // 鍵值對數量
|
||||
var capacity: Int // 雜湊表容量
|
||||
val loadThres: Double // 觸發擴容的負載因子閾值
|
||||
|
@ -1464,7 +1464,7 @@ index = hash(key) % capacity
|
||||
/* 建構子 */
|
||||
ArrayHashMap *newArrayHashMap() {
|
||||
ArrayHashMap *hmap = malloc(sizeof(ArrayHashMap));
|
||||
for (int i = 0; i < MAX_SIZE; i++) {
|
||||
for (int i=0; i < MAX_SIZE; i++) {
|
||||
hmap->buckets[i] = NULL;
|
||||
}
|
||||
return hmap;
|
||||
@ -1646,7 +1646,8 @@ index = hash(key) % capacity
|
||||
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
|
||||
}
|
||||
@ -1656,7 +1657,7 @@ index = hash(key) % capacity
|
||||
for (kv in pairSet()) {
|
||||
val key = kv.key
|
||||
val _val = kv._val
|
||||
println("${key} -> ${_val}")
|
||||
println("$key -> $_val")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -220,7 +220,9 @@ comments: true
|
||||
|
||||
/* 交換元素 */
|
||||
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
|
||||
}
|
||||
|
||||
/* 獲取堆積大小 */
|
||||
|
@ -650,7 +650,7 @@ comments: true
|
||||
|
||||
/* 獲取父節點的索引 */
|
||||
int parent(MaxHeap *maxHeap, int i) {
|
||||
return (i - 1) / 2;
|
||||
return (i - 1) / 2; // 向下取整
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -339,7 +339,27 @@ comments: true
|
||||
=== "Ruby"
|
||||
|
||||
```ruby title="binary_search.rb"
|
||||
[class]{}-[func]{binary_search}
|
||||
### 二分搜尋(雙閉區間) ###
|
||||
def binary_search(nums, target)
|
||||
# 初始化雙閉區間 [0, n-1] ,即 i, j 分別指向陣列首元素、尾元素
|
||||
i, j = 0, nums.length - 1
|
||||
|
||||
# 迴圈,當搜尋區間為空時跳出(當 i > j 時為空)
|
||||
while i <= j
|
||||
# 理論上 Ruby 的數字可以無限大(取決於記憶體大小),無須考慮大數越界問題
|
||||
m = (i + j) / 2 # 計算中點索引 m
|
||||
|
||||
if nums[m] < target
|
||||
i = m + 1 # 此情況說明 target 在區間 [m+1, j] 中
|
||||
elsif nums[m] > target
|
||||
j = m - 1 # 此情況說明 target 在區間 [i, m-1] 中
|
||||
else
|
||||
return m # 找到目標元素,返回其索引
|
||||
end
|
||||
end
|
||||
|
||||
-1 # 未找到目標元素,返回 -1
|
||||
end
|
||||
```
|
||||
|
||||
=== "Zig"
|
||||
@ -667,7 +687,27 @@ comments: true
|
||||
=== "Ruby"
|
||||
|
||||
```ruby title="binary_search.rb"
|
||||
[class]{}-[func]{binary_search_lcro}
|
||||
### 二分搜尋(左閉右開區間) ###
|
||||
def binary_search_lcro(nums, target)
|
||||
# 初始化左閉右開區間 [0, n) ,即 i, j 分別指向陣列首元素、尾元素+1
|
||||
i, j = 0, nums.length
|
||||
|
||||
# 迴圈,當搜尋區間為空時跳出(當 i = j 時為空)
|
||||
while i < j
|
||||
# 計算中點索引 m
|
||||
m = (i + j) / 2
|
||||
|
||||
if nums[m] < target
|
||||
i = m + 1 # 此情況說明 target 在區間 [m+1, j) 中
|
||||
elsif nums[m] > target
|
||||
j = m - 1 # 此情況說明 target 在區間 [i, m) 中
|
||||
else
|
||||
return m # 找到目標元素,返回其索引
|
||||
end
|
||||
end
|
||||
|
||||
-1 # 未找到目標元素,返回 -1
|
||||
end
|
||||
```
|
||||
|
||||
=== "Zig"
|
||||
|
@ -212,7 +212,16 @@ comments: true
|
||||
=== "Ruby"
|
||||
|
||||
```ruby title="binary_search_edge.rb"
|
||||
[class]{}-[func]{binary_search_left_edge}
|
||||
### 二分搜尋最左一個 target ###
|
||||
def binary_search_left_edge(nums, target)
|
||||
# 等價於查詢 target 的插入點
|
||||
i = binary_search_insertion(nums, target)
|
||||
|
||||
# 未找到 target ,返回 -1
|
||||
return -1 if i == nums.length || nums[i] != target
|
||||
|
||||
i # 找到 target ,返回索引 i
|
||||
end
|
||||
```
|
||||
|
||||
=== "Zig"
|
||||
@ -461,7 +470,19 @@ comments: true
|
||||
=== "Ruby"
|
||||
|
||||
```ruby title="binary_search_edge.rb"
|
||||
[class]{}-[func]{binary_search_right_edge}
|
||||
### 二分搜尋最右一個 target ###
|
||||
def binary_search_right_edge(nums, target)
|
||||
# 轉化為查詢最左一個 target + 1
|
||||
i = binary_search_insertion(nums, target + 1)
|
||||
|
||||
# j 指向最右一個 target ,i 指向首個大於 target 的元素
|
||||
j = i - 1
|
||||
|
||||
# 未找到 target ,返回 -1
|
||||
return -1 if j == -1 || nums[j] != target
|
||||
|
||||
j # 找到 target ,返回索引 j
|
||||
end
|
||||
```
|
||||
|
||||
=== "Zig"
|
||||
|
@ -293,7 +293,26 @@ comments: true
|
||||
=== "Ruby"
|
||||
|
||||
```ruby title="binary_search_insertion.rb"
|
||||
[class]{}-[func]{binary_search_insertion_simple}
|
||||
### 二分搜尋插入點(無重複元素) ###
|
||||
def binary_search_insertion_simple(nums, target)
|
||||
# 初始化雙閉區間 [0, n-1]
|
||||
i, j = 0, nums.length - 1
|
||||
|
||||
while i <= j
|
||||
# 計算中點索引 m
|
||||
m = (i + j) / 2
|
||||
|
||||
if nums[m] < target
|
||||
i = m + 1 # target 在區間 [m+1, j] 中
|
||||
elsif nums[m] > target
|
||||
j = m - 1 # target 在區間 [i, m-1] 中
|
||||
else
|
||||
return m # 找到 target ,返回插入點 m
|
||||
end
|
||||
end
|
||||
|
||||
i # 未找到 target ,返回插入點 i
|
||||
end
|
||||
```
|
||||
|
||||
=== "Zig"
|
||||
@ -625,7 +644,26 @@ comments: true
|
||||
=== "Ruby"
|
||||
|
||||
```ruby title="binary_search_insertion.rb"
|
||||
[class]{}-[func]{binary_search_insertion}
|
||||
### 二分搜尋插入點(存在重複元素) ###
|
||||
def binary_search_insertion(nums, target)
|
||||
# 初始化雙閉區間 [0, n-1]
|
||||
i, j = 0, nums.length - 1
|
||||
|
||||
while i <= j
|
||||
# 計算中點索引 m
|
||||
m = (i + j) / 2
|
||||
|
||||
if nums[m] < target
|
||||
i = m + 1 # target 在區間 [m+1, j] 中
|
||||
elsif nums[m] > target
|
||||
j = m - 1 # target 在區間 [i, m-1] 中
|
||||
else
|
||||
j = m - 1 # 首個小於 target 的元素在區間 [i, m-1] 中
|
||||
end
|
||||
end
|
||||
|
||||
i # 返回插入點 i
|
||||
end
|
||||
```
|
||||
|
||||
=== "Zig"
|
||||
|
@ -228,7 +228,17 @@ comments: true
|
||||
=== "Ruby"
|
||||
|
||||
```ruby title="two_sum.rb"
|
||||
[class]{}-[func]{two_sum_brute_force}
|
||||
### 方法一:暴力列舉 ###
|
||||
def two_sum_brute_force(nums, target)
|
||||
# 兩層迴圈,時間複雜度為 O(n^2)
|
||||
for i in 0...(nums.length - 1)
|
||||
for j in (i + 1)...nums.length
|
||||
return [i, j] if nums[i] + nums[j] == target
|
||||
end
|
||||
end
|
||||
|
||||
[]
|
||||
end
|
||||
```
|
||||
|
||||
=== "Zig"
|
||||
@ -531,7 +541,19 @@ comments: true
|
||||
=== "Ruby"
|
||||
|
||||
```ruby title="two_sum.rb"
|
||||
[class]{}-[func]{two_sum_hash_table}
|
||||
### 方法二:輔助雜湊表 ###
|
||||
def two_sum_hash_table(nums, target)
|
||||
# 輔助雜湊表,空間複雜度為 O(n)
|
||||
dic = {}
|
||||
# 單層迴圈,時間複雜度為 O(n)
|
||||
for i in 0...nums.length
|
||||
return [dic[target - nums[i]], i] if dic.has_key?(target - nums[i])
|
||||
|
||||
dic[nums[i]] = i
|
||||
end
|
||||
|
||||
[]
|
||||
end
|
||||
```
|
||||
|
||||
=== "Zig"
|
||||
|
@ -264,7 +264,9 @@ comments: true
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -571,7 +573,9 @@ comments: true
|
||||
for (j in 0..<i) {
|
||||
if (nums[j] > nums[j + 1]) {
|
||||
// 交換 nums[j] 與 nums[j + 1]
|
||||
nums[j] = nums[j + 1].also { nums[j] = nums[j + 1] }
|
||||
val temp = nums[j]
|
||||
nums[j] = nums[j + 1]
|
||||
nums[j + 1] = temp
|
||||
flag = true // 記錄交換元素
|
||||
}
|
||||
}
|
||||
|
@ -553,7 +553,9 @@ comments: true
|
||||
if (ma == i)
|
||||
break
|
||||
// 交換兩節點
|
||||
nums[i] = nums[ma].also { nums[ma] = nums[i] }
|
||||
val temp = nums[i]
|
||||
nums[i] = nums[ma]
|
||||
nums[ma] = temp
|
||||
// 迴圈向下堆積化
|
||||
i = ma
|
||||
}
|
||||
@ -568,7 +570,9 @@ comments: true
|
||||
// 從堆積中提取最大元素,迴圈 n-1 輪
|
||||
for (i in nums.size - 1 downTo 1) {
|
||||
// 交換根節點與最右葉節點(交換首元素與尾元素)
|
||||
nums[0] = nums[i].also { nums[i] = nums[0] }
|
||||
val temp = nums[0]
|
||||
nums[0] = nums[i]
|
||||
nums[i] = temp
|
||||
// 以根節點為起點,從頂至底進行堆積化
|
||||
siftDown(nums, i, 0)
|
||||
}
|
||||
|
@ -253,7 +253,21 @@ comments: true
|
||||
=== "Ruby"
|
||||
|
||||
```ruby title="insertion_sort.rb"
|
||||
[class]{}-[func]{insertion_sort}
|
||||
### 插入排序 ###
|
||||
def insertion_sort(nums)
|
||||
n = nums.length
|
||||
# 外迴圈:已排序區間為 [0, i-1]
|
||||
for i in 1...n
|
||||
base = nums[i]
|
||||
j = i - 1
|
||||
# 內迴圈:將 base 插入到已排序區間 [0, i-1] 中的正確位置
|
||||
while j >= 0 && nums[j] > base
|
||||
nums[j + 1] = nums[j] # 將 nums[j] 向右移動一位
|
||||
j -= 1
|
||||
end
|
||||
nums[j + 1] = base # 將 base 賦值到正確位置
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
=== "Zig"
|
||||
|
@ -302,19 +302,16 @@ comments: true
|
||||
nums[j] = tmp;
|
||||
}
|
||||
|
||||
/* 快速排序類別 */
|
||||
// 快速排序類別-哨兵劃分
|
||||
/* 哨兵劃分 */
|
||||
int partition(int nums[], int left, int right) {
|
||||
// 以 nums[left] 為基準數
|
||||
int i = left, j = right;
|
||||
while (i < j) {
|
||||
while (i < j && nums[j] >= nums[left]) {
|
||||
// 從右向左找首個小於基準數的元素
|
||||
j--;
|
||||
j--; // 從右向左找首個小於基準數的元素
|
||||
}
|
||||
while (i < j && nums[i] <= nums[left]) {
|
||||
// 從左向右找首個大於基準數的元素
|
||||
i++;
|
||||
i++; // 從左向右找首個大於基準數的元素
|
||||
}
|
||||
// 交換這兩個元素
|
||||
swap(nums, i, j);
|
||||
@ -331,7 +328,9 @@ comments: true
|
||||
```kotlin title="quick_sort.kt"
|
||||
/* 元素交換 */
|
||||
fun swap(nums: IntArray, i: Int, j: Int) {
|
||||
nums[i] = nums[j].also { nums[j] = nums[i] }
|
||||
val temp = nums[i]
|
||||
nums[i] = nums[j]
|
||||
nums[j] = temp
|
||||
}
|
||||
|
||||
/* 哨兵劃分 */
|
||||
@ -563,30 +562,7 @@ comments: true
|
||||
=== "C"
|
||||
|
||||
```c title="quick_sort.c"
|
||||
/* 快速排序類別 */
|
||||
// 快速排序類別-哨兵劃分
|
||||
int partition(int nums[], int left, int right) {
|
||||
// 以 nums[left] 為基準數
|
||||
int i = left, j = right;
|
||||
while (i < j) {
|
||||
while (i < j && nums[j] >= nums[left]) {
|
||||
// 從右向左找首個小於基準數的元素
|
||||
j--;
|
||||
}
|
||||
while (i < j && nums[i] <= nums[left]) {
|
||||
// 從左向右找首個大於基準數的元素
|
||||
i++;
|
||||
}
|
||||
// 交換這兩個元素
|
||||
swap(nums, i, j);
|
||||
}
|
||||
// 將基準數交換至兩子陣列的分界線
|
||||
swap(nums, i, left);
|
||||
// 返回基準數的索引
|
||||
return i;
|
||||
}
|
||||
|
||||
// 快速排序類別-快速排序
|
||||
/* 快速排序 */
|
||||
void quickSort(int nums[], int left, int right) {
|
||||
// 子陣列長度為 1 時終止遞迴
|
||||
if (left >= right) {
|
||||
@ -1022,8 +998,7 @@ comments: true
|
||||
=== "C"
|
||||
|
||||
```c title="quick_sort.c"
|
||||
/* 快速排序類別(中位基準數最佳化) */
|
||||
// 選取三個候選元素的中位數
|
||||
/* 選取三個候選元素的中位數 */
|
||||
int medianThree(int nums[], int left, int mid, int right) {
|
||||
int l = nums[left], m = nums[mid], r = nums[right];
|
||||
if ((l <= m && m <= r) || (r <= m && m <= l))
|
||||
@ -1354,8 +1329,7 @@ comments: true
|
||||
=== "C"
|
||||
|
||||
```c title="quick_sort.c"
|
||||
/* 快速排序類別(尾遞迴最佳化) */
|
||||
// 快速排序(尾遞迴最佳化)
|
||||
/* 快速排序(尾遞迴最佳化) */
|
||||
void quickSortTailCall(int nums[], int left, int right) {
|
||||
// 子陣列長度為 1 時終止
|
||||
while (left < right) {
|
||||
@ -1363,11 +1337,15 @@ comments: true
|
||||
int pivot = partition(nums, left, right);
|
||||
// 對兩個子陣列中較短的那個執行快速排序
|
||||
if (pivot - left < right - pivot) {
|
||||
quickSortTailCall(nums, left, pivot - 1); // 遞迴排序左子陣列
|
||||
left = pivot + 1; // 剩餘未排序區間為 [pivot + 1, right]
|
||||
// 遞迴排序左子陣列
|
||||
quickSortTailCall(nums, left, pivot - 1);
|
||||
// 剩餘未排序區間為 [pivot + 1, right]
|
||||
left = pivot + 1;
|
||||
} else {
|
||||
quickSortTailCall(nums, pivot + 1, right); // 遞迴排序右子陣列
|
||||
right = pivot - 1; // 剩餘未排序區間為 [left, pivot - 1]
|
||||
// 遞迴排序右子陣列
|
||||
quickSortTailCall(nums, pivot + 1, right);
|
||||
// 剩餘未排序區間為 [left, pivot - 1]
|
||||
right = pivot - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -296,7 +296,9 @@ comments: true
|
||||
k = j // 記錄最小元素的索引
|
||||
}
|
||||
// 將該最小元素與未排序區間的首個元素交換
|
||||
nums[i] = nums[k].also { nums[k] = nums[i] }
|
||||
val temp = nums[i]
|
||||
nums[i] = nums[k]
|
||||
nums[k] = temp
|
||||
}
|
||||
}
|
||||
```
|
||||
|
@ -1092,7 +1092,7 @@ comments: true
|
||||
fun pop(): Int? {
|
||||
val num = peek()
|
||||
stackPeek = stackPeek?.next
|
||||
stkSize--;
|
||||
stkSize--
|
||||
return num
|
||||
}
|
||||
|
||||
|
@ -125,7 +125,7 @@ comments: true
|
||||
```kotlin title=""
|
||||
/* 二元樹的陣列表示 */
|
||||
// 使用 null 來表示空位
|
||||
val tree = mutableListOf( 1, 2, 3, 4, null, 6, 7, 8, 9, null, null, 12, null, null, 15 )
|
||||
val tree = arrayOf( 1, 2, 3, 4, null, 6, 7, 8, 9, null, null, 12, null, null, 15 )
|
||||
```
|
||||
|
||||
=== "Ruby"
|
||||
@ -1172,7 +1172,7 @@ comments: true
|
||||
=== "Kotlin"
|
||||
|
||||
```kotlin title="array_binary_tree.kt"
|
||||
/* 建構子 */
|
||||
/* 陣列表示下的二元樹類別 */
|
||||
class ArrayBinaryTree(val tree: MutableList<Int?>) {
|
||||
/* 串列容量 */
|
||||
fun size(): Int {
|
||||
|
Reference in New Issue
Block a user