mirror of
https://github.com/krahets/hello-algo.git
synced 2024-12-24 21:26:27 +08:00
Add build script for JS and TS codes.
This commit is contained in:
parent
22b7d65d20
commit
05f0054005
28 changed files with 227 additions and 2217 deletions
|
@ -7,38 +7,32 @@
|
|||
#include "../include/include.hpp"
|
||||
|
||||
/* 方法一:暴力枚举 */
|
||||
class SolutionBruteForce {
|
||||
public:
|
||||
vector<int> twoSum(vector<int>& nums, int target) {
|
||||
int size = nums.size();
|
||||
// 两层循环,时间复杂度 O(n^2)
|
||||
for (int i = 0; i < size - 1; i++) {
|
||||
for (int j = i + 1; j < size; j++) {
|
||||
if (nums[i] + nums[j] == target)
|
||||
return { i, j };
|
||||
}
|
||||
vector<int> twoSumBruteForce(vector<int>& nums, int target) {
|
||||
int size = nums.size();
|
||||
// 两层循环,时间复杂度 O(n^2)
|
||||
for (int i = 0; i < size - 1; i++) {
|
||||
for (int j = i + 1; j < size; j++) {
|
||||
if (nums[i] + nums[j] == target)
|
||||
return { i, j };
|
||||
}
|
||||
return {};
|
||||
}
|
||||
};
|
||||
return {};
|
||||
}
|
||||
|
||||
/* 方法二:辅助哈希表 */
|
||||
class SolutionHashMap {
|
||||
public:
|
||||
vector<int> twoSum(vector<int>& nums, int target) {
|
||||
int size = nums.size();
|
||||
// 辅助哈希表,空间复杂度 O(n)
|
||||
unordered_map<int, int> dic;
|
||||
// 单层循环,时间复杂度 O(n)
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (dic.find(target - nums[i]) != dic.end()) {
|
||||
return { dic[target - nums[i]], i };
|
||||
}
|
||||
dic.emplace(nums[i], i);
|
||||
vector<int> twoSumHashTable(vector<int>& nums, int target) {
|
||||
int size = nums.size();
|
||||
// 辅助哈希表,空间复杂度 O(n)
|
||||
unordered_map<int, int> dic;
|
||||
// 单层循环,时间复杂度 O(n)
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (dic.find(target - nums[i]) != dic.end()) {
|
||||
return { dic[target - nums[i]], i };
|
||||
}
|
||||
return {};
|
||||
dic.emplace(nums[i], i);
|
||||
}
|
||||
};
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
int main() {
|
||||
|
@ -48,19 +42,13 @@ int main() {
|
|||
|
||||
// ====== Driver Code ======
|
||||
// 方法一
|
||||
SolutionBruteForce* slt1 = new SolutionBruteForce();
|
||||
vector<int> res = slt1->twoSum(nums, target);
|
||||
vector<int> res = twoSumBruteForce(nums, target);
|
||||
cout << "方法一 res = ";
|
||||
PrintUtil::printVector(res);
|
||||
// 方法二
|
||||
SolutionHashMap* slt2 = new SolutionHashMap();
|
||||
res = slt2->twoSum(nums, target);
|
||||
res = twoSumHashTable(nums, target);
|
||||
cout << "方法二 res = ";
|
||||
PrintUtil::printVector(res);
|
||||
|
||||
// 释放内存
|
||||
delete slt1;
|
||||
delete slt2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -8,10 +8,10 @@ using NUnit.Framework;
|
|||
|
||||
namespace hello_algo.chapter_computational_complexity
|
||||
{
|
||||
/* 方法一:暴力枚举 */
|
||||
class SolutionBruteForce
|
||||
public class leetcode_two_sum
|
||||
{
|
||||
public int[] twoSum(int[] nums, int target)
|
||||
/* 方法一:暴力枚举 */
|
||||
public static int[] twoSumBruteForce(int[] nums, int target)
|
||||
{
|
||||
int size = nums.Length;
|
||||
// 两层循环,时间复杂度 O(n^2)
|
||||
|
@ -25,12 +25,9 @@ namespace hello_algo.chapter_computational_complexity
|
|||
}
|
||||
return new int[0];
|
||||
}
|
||||
}
|
||||
|
||||
/* 方法二:辅助哈希表 */
|
||||
class SolutionHashMap
|
||||
{
|
||||
public int[] twoSum(int[] nums, int target)
|
||||
/* 方法二:辅助哈希表 */
|
||||
public static int[] twoSumHashTable(int[] nums, int target)
|
||||
{
|
||||
int size = nums.Length;
|
||||
// 辅助哈希表,空间复杂度 O(n)
|
||||
|
@ -46,10 +43,7 @@ namespace hello_algo.chapter_computational_complexity
|
|||
}
|
||||
return new int[0];
|
||||
}
|
||||
}
|
||||
|
||||
public class leetcode_two_sum
|
||||
{
|
||||
[Test]
|
||||
public void Test()
|
||||
{
|
||||
|
@ -59,13 +53,11 @@ namespace hello_algo.chapter_computational_complexity
|
|||
|
||||
// ====== Driver Code ======
|
||||
// 方法一
|
||||
SolutionBruteForce slt1 = new SolutionBruteForce();
|
||||
int[] res = slt1.twoSum(nums, target);
|
||||
int[] res = twoSumBruteForce(nums, target);
|
||||
Console.WriteLine("方法一 res = " + string.Join(",", res));
|
||||
// 方法二
|
||||
SolutionHashMap slt2 = new SolutionHashMap();
|
||||
res = slt2.twoSum(nums, target);
|
||||
res = twoSumHashTable(nums, target);
|
||||
Console.WriteLine("方法二 res = " + string.Join(",", res));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,9 +8,10 @@ package chapter_computational_complexity;
|
|||
|
||||
import java.util.*;
|
||||
|
||||
/* 方法一:暴力枚举 */
|
||||
class SolutionBruteForce {
|
||||
public int[] twoSum(int[] nums, int target) {
|
||||
|
||||
public class leetcode_two_sum {
|
||||
/* 方法一:暴力枚举 */
|
||||
static int[] twoSumBruteForce(int[] nums, int target) {
|
||||
int size = nums.length;
|
||||
// 两层循环,时间复杂度 O(n^2)
|
||||
for (int i = 0; i < size - 1; i++) {
|
||||
|
@ -21,11 +22,9 @@ class SolutionBruteForce {
|
|||
}
|
||||
return new int[0];
|
||||
}
|
||||
}
|
||||
|
||||
/* 方法二:辅助哈希表 */
|
||||
class SolutionHashMap {
|
||||
public int[] twoSum(int[] nums, int target) {
|
||||
/* 方法二:辅助哈希表 */
|
||||
static int[] twoSumHashTable(int[] nums, int target) {
|
||||
int size = nums.length;
|
||||
// 辅助哈希表,空间复杂度 O(n)
|
||||
Map<Integer, Integer> dic = new HashMap<>();
|
||||
|
@ -38,9 +37,7 @@ class SolutionHashMap {
|
|||
}
|
||||
return new int[0];
|
||||
}
|
||||
}
|
||||
|
||||
public class leetcode_two_sum {
|
||||
public static void main(String[] args) {
|
||||
// ======= Test Case =======
|
||||
int[] nums = { 2,7,11,15 };
|
||||
|
@ -48,12 +45,10 @@ public class leetcode_two_sum {
|
|||
|
||||
// ====== Driver Code ======
|
||||
// 方法一
|
||||
SolutionBruteForce slt1 = new SolutionBruteForce();
|
||||
int[] res = slt1.twoSum(nums, target);
|
||||
int[] res = twoSumBruteForce(nums, target);
|
||||
System.out.println("方法一 res = " + Arrays.toString(res));
|
||||
// 方法二
|
||||
SolutionHashMap slt2 = new SolutionHashMap();
|
||||
res = slt2.twoSum(nums, target);
|
||||
res = twoSumHashTable(nums, target);
|
||||
System.out.println("方法二 res = " + Arrays.toString(res));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* Author: IsChristina (christinaxia77@foxmail.com)
|
||||
*/
|
||||
|
||||
/* 随机访问元素 */
|
||||
/* 随机返回一个数组元素 */
|
||||
function randomAccess(nums) {
|
||||
// 在区间 [0, nums.length) 中随机抽取一个数字
|
||||
const random_index = Math.floor(Math.random() * nums.length);
|
||||
|
|
|
@ -44,7 +44,7 @@ class LinkedListStack {
|
|||
/* 访问栈顶元素 */
|
||||
peek() {
|
||||
if (!this.#stackPeek)
|
||||
throw new Error("栈为空!");
|
||||
throw new Error("栈为空");
|
||||
return this.#stackPeek.val;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,26 +9,24 @@ sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
|
|||
from include import *
|
||||
|
||||
""" 方法一:暴力枚举 """
|
||||
class SolutionBruteForce:
|
||||
def twoSum(self, nums: List[int], target: int) -> List[int]:
|
||||
# 两层循环,时间复杂度 O(n^2)
|
||||
for i in range(len(nums) - 1):
|
||||
for j in range(i + 1, len(nums)):
|
||||
if nums[i] + nums[j] == target:
|
||||
return i, j
|
||||
return []
|
||||
def two_sum_brute_force(nums: List[int], target: int) -> List[int]:
|
||||
# 两层循环,时间复杂度 O(n^2)
|
||||
for i in range(len(nums) - 1):
|
||||
for j in range(i + 1, len(nums)):
|
||||
if nums[i] + nums[j] == target:
|
||||
return i, j
|
||||
return []
|
||||
|
||||
""" 方法二:辅助哈希表 """
|
||||
class SolutionHashMap:
|
||||
def twoSum(self, nums: List[int], target: int) -> List[int]:
|
||||
# 辅助哈希表,空间复杂度 O(n)
|
||||
dic = {}
|
||||
# 单层循环,时间复杂度 O(n)
|
||||
for i in range(len(nums)):
|
||||
if target - nums[i] in dic:
|
||||
return dic[target - nums[i]], i
|
||||
dic[nums[i]] = i
|
||||
return []
|
||||
def two_sum_hash_table(nums: List[int], target: int) -> List[int]:
|
||||
# 辅助哈希表,空间复杂度 O(n)
|
||||
dic = {}
|
||||
# 单层循环,时间复杂度 O(n)
|
||||
for i in range(len(nums)):
|
||||
if target - nums[i] in dic:
|
||||
return dic[target - nums[i]], i
|
||||
dic[nums[i]] = i
|
||||
return []
|
||||
|
||||
|
||||
""" Driver Code """
|
||||
|
@ -39,8 +37,8 @@ if __name__ == '__main__':
|
|||
|
||||
# ====== Driver Code ======
|
||||
# 方法一
|
||||
res = SolutionBruteForce().twoSum(nums, target)
|
||||
res = two_sum_brute_force(nums, target)
|
||||
print("方法一 res =", res)
|
||||
# 方法二
|
||||
res = SolutionHashMap().twoSum(nums, target)
|
||||
res = two_sum_hash_table(nums, target)
|
||||
print("方法二 res =", res)
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
/* 二分查找(双闭区间) */
|
||||
const binarySearch = function (nums: number[], target: number): number {
|
||||
function binarySearch(nums: number[], target: number): number {
|
||||
// 初始化双闭区间 [0, n-1] ,即 i, j 分别指向数组首元素、尾元素
|
||||
let i = 0, j = nums.length - 1;
|
||||
// 循环,当搜索区间为空时跳出(当 i > j 时为空)
|
||||
|
@ -23,7 +23,7 @@ const binarySearch = function (nums: number[], target: number): number {
|
|||
}
|
||||
|
||||
/* 二分查找(左闭右开) */
|
||||
const binarySearch1 = function (nums: number[], target: number): number {
|
||||
function binarySearch1(nums: number[], target: number): number {
|
||||
// 初始化左闭右开 [0, n) ,即 i, j 分别指向数组首元素、尾元素+1
|
||||
let i = 0, j = nums.length;
|
||||
// 循环,当搜索区间为空时跳出(当 i = j 时为空)
|
||||
|
|
|
@ -148,27 +148,13 @@ elementAddr = firtstElementAddr + elementLength * elementIndex
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="array.js"
|
||||
/* 随机返回一个数组元素 */
|
||||
function randomAccess(nums) {
|
||||
// 在区间 [0, nums.length) 中随机抽取一个数字
|
||||
const random_index = Math.floor(Math.random() * nums.length);
|
||||
// 获取并返回随机元素
|
||||
const random_num = nums[random_index];
|
||||
return random_num;
|
||||
}
|
||||
[class]{}-[func]{randomAccess}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="array.ts"
|
||||
/* 随机返回一个数组元素 */
|
||||
function randomAccess(nums: number[]): number {
|
||||
// 在区间 [0, nums.length) 中随机抽取一个数字
|
||||
const random_index = Math.floor(Math.random() * nums.length);
|
||||
// 获取并返回随机元素
|
||||
const random_num = nums[random_index];
|
||||
return random_num;
|
||||
}
|
||||
[class]{}-[func]{randomAccess}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
@ -259,33 +245,13 @@ elementAddr = firtstElementAddr + elementLength * elementIndex
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="array.js"
|
||||
/* 扩展数组长度 */
|
||||
function extend(nums, enlarge) {
|
||||
// 初始化一个扩展长度后的数组
|
||||
const res = new Array(nums.length + enlarge).fill(0);
|
||||
// 将原数组中的所有元素复制到新数组
|
||||
for (let i = 0; i < nums.length; i++) {
|
||||
res[i] = nums[i];
|
||||
}
|
||||
// 返回扩展后的新数组
|
||||
return res;
|
||||
}
|
||||
[class]{}-[func]{extend}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="array.ts"
|
||||
/* 扩展数组长度 */
|
||||
function extend(nums: number[], enlarge: number): number[] {
|
||||
// 初始化一个扩展长度后的数组
|
||||
const res = new Array(nums.length + enlarge).fill(0);
|
||||
// 将原数组中的所有元素复制到新数组
|
||||
for (let i = 0; i < nums.length; i++) {
|
||||
res[i] = nums[i];
|
||||
}
|
||||
// 返回扩展后的新数组
|
||||
return res;
|
||||
}
|
||||
[class]{}-[func]{extend}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
@ -402,45 +368,17 @@ elementAddr = firtstElementAddr + elementLength * elementIndex
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="array.js"
|
||||
/* 在数组的索引 index 处插入元素 num */
|
||||
function insert(nums, num, index) {
|
||||
// 把索引 index 以及之后的所有元素向后移动一位
|
||||
for (let i = nums.length - 1; i > index; i--) {
|
||||
nums[i] = nums[i - 1];
|
||||
}
|
||||
// 将 num 赋给 index 处元素
|
||||
nums[index] = num;
|
||||
}
|
||||
|
||||
/* 删除索引 index 处元素 */
|
||||
function remove(nums, index) {
|
||||
// 把索引 index 之后的所有元素向前移动一位
|
||||
for (let i = index; i < nums.length - 1; i++) {
|
||||
nums[i] = nums[i + 1];
|
||||
}
|
||||
}
|
||||
[class]{}-[func]{insert}
|
||||
|
||||
[class]{}-[func]{remove}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="array.ts"
|
||||
/* 在数组的索引 index 处插入元素 num */
|
||||
function insert(nums: number[], num: number, index: number): void {
|
||||
// 把索引 index 以及之后的所有元素向后移动一位
|
||||
for (let i = nums.length - 1; i > index; i--) {
|
||||
nums[i] = nums[i - 1];
|
||||
}
|
||||
// 将 num 赋给 index 处元素
|
||||
nums[index] = num;
|
||||
}
|
||||
|
||||
/* 删除索引 index 处元素 */
|
||||
function remove(nums: number[], index: number): void {
|
||||
// 把索引 index 之后的所有元素向前移动一位
|
||||
for (let i = index; i < nums.length - 1; i++) {
|
||||
nums[i] = nums[i + 1];
|
||||
}
|
||||
}
|
||||
[class]{}-[func]{insert}
|
||||
|
||||
[class]{}-[func]{remove}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
@ -563,35 +501,13 @@ elementAddr = firtstElementAddr + elementLength * elementIndex
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="array.js"
|
||||
/* 遍历数组 */
|
||||
function traverse(nums) {
|
||||
let count = 0;
|
||||
// 通过索引遍历数组
|
||||
for (let i = 0; i < nums.length; i++) {
|
||||
count++;
|
||||
}
|
||||
// 直接遍历数组
|
||||
for (let num of nums) {
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
[class]{}-[func]{traverse}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="array.ts"
|
||||
/* 遍历数组 */
|
||||
function traverse(nums: number[]): void {
|
||||
let count = 0;
|
||||
// 通过索引遍历数组
|
||||
for (let i = 0; i < nums.length; i++) {
|
||||
count++;
|
||||
}
|
||||
// 直接遍历数组
|
||||
for(let num of nums){
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
[class]{}-[func]{traverse}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
@ -695,27 +611,13 @@ elementAddr = firtstElementAddr + elementLength * elementIndex
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="array.js"
|
||||
/* 在数组中查找指定元素 */
|
||||
function find(nums, target) {
|
||||
for (let i = 0; i < nums.length; i++) {
|
||||
if (nums[i] == target) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
[class]{}-[func]{find}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="array.ts"
|
||||
/* 在数组中查找指定元素 */
|
||||
function find(nums: number[], target: number): number {
|
||||
for (let i = 0; i < nums.length; i++) {
|
||||
if (nums[i] === target) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
[class]{}-[func]{find}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
|
|
@ -538,30 +538,13 @@ comments: true
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="linked_list.js"
|
||||
/* 访问链表中索引为 index 的结点 */
|
||||
function access(head, index) {
|
||||
for (let i = 0; i < index; i++) {
|
||||
if (!head)
|
||||
return null;
|
||||
head = head.next;
|
||||
}
|
||||
return head;
|
||||
}
|
||||
[class]{}-[func]{access}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="linked_list.ts"
|
||||
/* 访问链表中索引为 index 的结点 */
|
||||
function access(head: ListNode | null, index: number): ListNode | null {
|
||||
for (let i = 0; i < index; i++) {
|
||||
if (!head) {
|
||||
return null;
|
||||
}
|
||||
head = head.next;
|
||||
}
|
||||
return head;
|
||||
}
|
||||
[class]{}-[func]{access}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
@ -661,35 +644,13 @@ comments: true
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="linked_list.js"
|
||||
/* 在链表中查找值为 target 的首个结点 */
|
||||
function find(head, target) {
|
||||
let index = 0;
|
||||
while (head !== null) {
|
||||
if (head.val === target) {
|
||||
return index;
|
||||
}
|
||||
head = head.next;
|
||||
index += 1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
[class]{}-[func]{find}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="linked_list.ts"
|
||||
/* 在链表中查找值为 target 的首个结点 */
|
||||
function find(head: ListNode | null, target: number): number {
|
||||
let index = 0;
|
||||
while (head !== null) {
|
||||
if (head.val === target) {
|
||||
return index;
|
||||
}
|
||||
head = head.next;
|
||||
index += 1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
[class]{}-[func]{find}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
|
|
@ -836,190 +836,13 @@ comments: true
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="my_list.js"
|
||||
/* 列表类简易实现 */
|
||||
class MyList {
|
||||
#nums = new Array(); // 数组(存储列表元素)
|
||||
#capacity = 10; // 列表容量
|
||||
#size = 0; // 列表长度(即当前元素数量)
|
||||
#extendRatio = 2; // 每次列表扩容的倍数
|
||||
|
||||
/* 构造函数 */
|
||||
constructor() {
|
||||
this.#nums = new Array(this.#capacity);
|
||||
}
|
||||
|
||||
/* 获取列表长度(即当前元素数量)*/
|
||||
size() {
|
||||
return this.#size;
|
||||
}
|
||||
|
||||
/* 获取列表容量 */
|
||||
capacity() {
|
||||
return this.#capacity;
|
||||
}
|
||||
|
||||
/* 访问元素 */
|
||||
get(index) {
|
||||
// 索引如果越界则抛出异常,下同
|
||||
if (index < 0 || index >= this.#size)
|
||||
throw new Error('索引越界');
|
||||
return this.#nums[index];
|
||||
}
|
||||
|
||||
/* 更新元素 */
|
||||
set(index, num) {
|
||||
if (index < 0 || index >= this.#size)
|
||||
throw new Error('索引越界');
|
||||
this.#nums[index] = num;
|
||||
}
|
||||
|
||||
/* 尾部添加元素 */
|
||||
add(num) {
|
||||
// 如果长度等于容量,则需要扩容
|
||||
if (this.#size === this.#capacity) {
|
||||
this.extendCapacity();
|
||||
}
|
||||
// 将新元素添加到列表尾部
|
||||
this.#nums[this.#size] = num;
|
||||
this.#size++;
|
||||
}
|
||||
|
||||
/* 中间插入元素 */
|
||||
insert(index, num) {
|
||||
if (index < 0 || index >= this.#size)
|
||||
throw new Error('索引越界');
|
||||
// 元素数量超出容量时,触发扩容机制
|
||||
if (this.#size === this.#capacity) {
|
||||
this.extendCapacity();
|
||||
}
|
||||
// 将索引 index 以及之后的元素都向后移动一位
|
||||
for (let j = this.#size - 1; j >= index; j--) {
|
||||
this.#nums[j + 1] = this.#nums[j];
|
||||
}
|
||||
// 更新元素数量
|
||||
this.#nums[index] = num;
|
||||
this.#size++;
|
||||
}
|
||||
|
||||
/* 删除元素 */
|
||||
remove(index) {
|
||||
if (index < 0 || index >= this.#size)
|
||||
throw new Error('索引越界');
|
||||
let num = this.#nums[index];
|
||||
// 将索引 index 之后的元素都向前移动一位
|
||||
for (let j = index; j < this.#size - 1; j++) {
|
||||
this.#nums[j] = this.#nums[j + 1];
|
||||
}
|
||||
// 更新元素数量
|
||||
this.#size--;
|
||||
// 返回被删除元素
|
||||
return num;
|
||||
}
|
||||
|
||||
/* 列表扩容 */
|
||||
extendCapacity() {
|
||||
// 新建一个长度为 size 的数组,并将原数组拷贝到新数组
|
||||
this.#nums = this.#nums.concat(
|
||||
new Array(this.capacity() * (this.#extendRatio - 1))
|
||||
);
|
||||
// 更新列表容量
|
||||
this.#capacity = this.#nums.length;
|
||||
}
|
||||
}
|
||||
[class]{MyList}-[func]{}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="my_list.ts"
|
||||
/* 列表类简易实现 */
|
||||
class MyList {
|
||||
private nums: Array<number>; // 数组(存储列表元素)
|
||||
private _capacity: number = 10; // 列表容量
|
||||
private _size: number = 0; // 列表长度(即当前元素数量)
|
||||
private extendRatio: number = 2; // 每次列表扩容的倍数
|
||||
|
||||
/* 构造函数 */
|
||||
constructor() {
|
||||
this.nums = new Array(this._capacity);
|
||||
}
|
||||
|
||||
/* 获取列表长度(即当前元素数量)*/
|
||||
public size(): number {
|
||||
return this._size;
|
||||
}
|
||||
|
||||
/* 获取列表容量 */
|
||||
public capacity(): number {
|
||||
return this._capacity;
|
||||
}
|
||||
|
||||
/* 访问元素 */
|
||||
public get(index: number): number {
|
||||
// 索引如果越界则抛出异常,下同
|
||||
if (index < 0 || index >= this._size)
|
||||
throw new Error('索引越界');
|
||||
return this.nums[index];
|
||||
}
|
||||
|
||||
/* 更新元素 */
|
||||
public set(index: number, num: number): void {
|
||||
if (index < 0 || index >= this._size)
|
||||
throw new Error('索引越界');
|
||||
this.nums[index] = num;
|
||||
}
|
||||
|
||||
/* 尾部添加元素 */
|
||||
public add(num: number): void {
|
||||
// 如果长度等于容量,则需要扩容
|
||||
if (this._size === this._capacity)
|
||||
this.extendCapacity();
|
||||
// 将新元素添加到列表尾部
|
||||
this.nums[this._size] = num;
|
||||
this._size++;
|
||||
}
|
||||
|
||||
/* 中间插入元素 */
|
||||
public insert(index: number, num: number): void {
|
||||
if (index < 0 || index >= this._size)
|
||||
throw new Error('索引越界');
|
||||
// 元素数量超出容量时,触发扩容机制
|
||||
if (this._size === this._capacity) {
|
||||
this.extendCapacity();
|
||||
}
|
||||
// 将索引 index 以及之后的元素都向后移动一位
|
||||
for (let j = this._size - 1; j >= index; j--) {
|
||||
this.nums[j + 1] = this.nums[j];
|
||||
}
|
||||
// 更新元素数量
|
||||
this.nums[index] = num;
|
||||
this._size++;
|
||||
}
|
||||
|
||||
/* 删除元素 */
|
||||
public remove(index: number): number {
|
||||
if (index < 0 || index >= this._size)
|
||||
throw new Error('索引越界');
|
||||
let num = this.nums[index];
|
||||
// 将索引 index 之后的元素都向前移动一位
|
||||
for (let j = index; j < this._size - 1; j++) {
|
||||
this.nums[j] = this.nums[j + 1];
|
||||
}
|
||||
// 更新元素数量
|
||||
this._size--;
|
||||
// 返回被删除元素
|
||||
return num;
|
||||
}
|
||||
|
||||
/* 列表扩容 */
|
||||
public extendCapacity(): void {
|
||||
// 新建一个长度为 size 的数组,并将原数组拷贝到新数组
|
||||
this.nums = this.nums.concat(
|
||||
new Array(this.capacity() * (this.extendRatio - 1))
|
||||
);
|
||||
// 更新列表容量
|
||||
this._capacity = this.nums.length;
|
||||
}
|
||||
}
|
||||
[class]{MyList}-[func]{}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
|
|
@ -623,43 +623,13 @@ $$
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="space_complexity.js"
|
||||
/* 常数阶 */
|
||||
function constant(n) {
|
||||
// 常量、变量、对象占用 O(1) 空间
|
||||
const a = 0;
|
||||
const b = 0;
|
||||
const nums = new Array(10000);
|
||||
const node = new ListNode(0);
|
||||
// 循环中的变量占用 O(1) 空间
|
||||
for (let i = 0; i < n; i++) {
|
||||
const c = 0;
|
||||
}
|
||||
// 循环中的函数占用 O(1) 空间
|
||||
for (let i = 0; i < n; i++) {
|
||||
constFunc();
|
||||
}
|
||||
}
|
||||
[class]{}-[func]{constant}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="space_complexity.ts"
|
||||
/* 常数阶 */
|
||||
function constant(n: number): void {
|
||||
// 常量、变量、对象占用 O(1) 空间
|
||||
const a = 0;
|
||||
const b = 0;
|
||||
const nums = new Array(10000);
|
||||
const node = new ListNode(0);
|
||||
// 循环中的变量占用 O(1) 空间
|
||||
for (let i = 0; i < n; i++) {
|
||||
const c = 0;
|
||||
}
|
||||
// 循环中的函数占用 O(1) 空间
|
||||
for (let i = 0; i < n; i++) {
|
||||
constFunc();
|
||||
}
|
||||
}
|
||||
[class]{}-[func]{constant}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
@ -786,41 +756,13 @@ $$
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="space_complexity.js"
|
||||
/* 线性阶 */
|
||||
function linear(n) {
|
||||
// 长度为 n 的数组占用 O(n) 空间
|
||||
const nums = new Array(n);
|
||||
// 长度为 n 的列表占用 O(n) 空间
|
||||
const nodes = [];
|
||||
for (let i = 0; i < n; i++) {
|
||||
nodes.push(new ListNode(i));
|
||||
}
|
||||
// 长度为 n 的哈希表占用 O(n) 空间
|
||||
const map = new Map();
|
||||
for (let i = 0; i < n; i++) {
|
||||
map.set(i, i.toString());
|
||||
}
|
||||
}
|
||||
[class]{}-[func]{linear}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="space_complexity.ts"
|
||||
/* 线性阶 */
|
||||
function linear(n: number): void {
|
||||
// 长度为 n 的数组占用 O(n) 空间
|
||||
const nums = new Array(n);
|
||||
// 长度为 n 的列表占用 O(n) 空间
|
||||
const nodes: ListNode[] = [];
|
||||
for (let i = 0; i < n; i++) {
|
||||
nodes.push(new ListNode(i));
|
||||
}
|
||||
// 长度为 n 的哈希表占用 O(n) 空间
|
||||
const map = new Map();
|
||||
for (let i = 0; i < n; i++) {
|
||||
map.set(i, i.toString());
|
||||
}
|
||||
}
|
||||
[class]{}-[func]{linear}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
@ -929,23 +871,13 @@ $$
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="space_complexity.js"
|
||||
/* 线性阶(递归实现) */
|
||||
function linearRecur(n) {
|
||||
console.log(`递归 n = ${n}`);
|
||||
if (n === 1) return;
|
||||
linearRecur(n - 1);
|
||||
}
|
||||
[class]{}-[func]{linearRecur}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="space_complexity.ts"
|
||||
/* 线性阶(递归实现) */
|
||||
function linearRecur(n: number): void {
|
||||
console.log(`递归 n = ${n}`);
|
||||
if (n === 1) return;
|
||||
linearRecur(n - 1);
|
||||
}
|
||||
[class]{}-[func]{linearRecur}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
@ -1032,39 +964,13 @@ $$
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="space_complexity.js"
|
||||
/* 平方阶 */
|
||||
function quadratic(n) {
|
||||
// 矩阵占用 O(n^2) 空间
|
||||
const numMatrix = Array(n).fill(null).map(() => Array(n).fill(null));
|
||||
// 二维列表占用 O(n^2) 空间
|
||||
const numList = [];
|
||||
for (let i = 0; i < n; i++) {
|
||||
const tmp = [];
|
||||
for (let j = 0; j < n; j++) {
|
||||
tmp.push(0);
|
||||
}
|
||||
numList.push(tmp);
|
||||
}
|
||||
}
|
||||
[class]{}-[func]{quadratic}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="space_complexity.ts"
|
||||
/* 平方阶 */
|
||||
function quadratic(n: number): void {
|
||||
// 矩阵占用 O(n^2) 空间
|
||||
const numMatrix = Array(n).fill(null).map(() => Array(n).fill(null));
|
||||
// 二维列表占用 O(n^2) 空间
|
||||
const numList = [];
|
||||
for (let i = 0; i < n; i++) {
|
||||
const tmp = [];
|
||||
for (let j = 0; j < n; j++) {
|
||||
tmp.push(0);
|
||||
}
|
||||
numList.push(tmp);
|
||||
}
|
||||
}
|
||||
[class]{}-[func]{quadratic}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
@ -1163,25 +1069,13 @@ $$
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="space_complexity.js"
|
||||
/* 平方阶(递归实现) */
|
||||
function quadraticRecur(n) {
|
||||
if (n <= 0) return 0;
|
||||
const nums = new Array(n);
|
||||
console.log(`递归 n = ${n} 中的 nums 长度 = ${nums.length}`);
|
||||
return quadraticRecur(n - 1);
|
||||
}
|
||||
[class]{}-[func]{quadraticRecur}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="space_complexity.ts"
|
||||
/* 平方阶(递归实现) */
|
||||
function quadraticRecur(n: number): number {
|
||||
if (n <= 0) return 0;
|
||||
const nums = new Array(n);
|
||||
console.log(`递归 n = ${n} 中的 nums 长度 = ${nums.length}`);
|
||||
return quadraticRecur(n - 1);
|
||||
}
|
||||
[class]{}-[func]{quadraticRecur}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
@ -1273,27 +1167,13 @@ $$
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="space_complexity.js"
|
||||
/* 指数阶(建立满二叉树) */
|
||||
function buildTree(n) {
|
||||
if (n === 0) return null;
|
||||
const root = new TreeNode(0);
|
||||
root.left = buildTree(n - 1);
|
||||
root.right = buildTree(n - 1);
|
||||
return root;
|
||||
}
|
||||
[class]{}-[func]{buildTree}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="space_complexity.ts"
|
||||
/* 指数阶(建立满二叉树) */
|
||||
function buildTree(n: number): TreeNode | null {
|
||||
if (n === 0) return null;
|
||||
const root = new TreeNode(0);
|
||||
root.left = buildTree(n - 1);
|
||||
root.right = buildTree(n - 1);
|
||||
return root;
|
||||
}
|
||||
[class]{}-[func]{buildTree}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
|
|
@ -33,19 +33,19 @@ comments: true
|
|||
=== "Java"
|
||||
|
||||
```java title="leetcode_two_sum.java"
|
||||
[class]{SolutionBruteForce}-[func]{}
|
||||
[class]{leetcode_two_sum}-[func]{twoSumBruteForce}
|
||||
```
|
||||
|
||||
=== "C++"
|
||||
|
||||
```cpp title="leetcode_two_sum.cpp"
|
||||
[class]{SolutionBruteForce}-[func]{}
|
||||
[class]{}-[func]{twoSumBruteForce}
|
||||
```
|
||||
|
||||
=== "Python"
|
||||
|
||||
```python title="leetcode_two_sum.py"
|
||||
[class]{SolutionBruteForce}-[func]{}
|
||||
[class]{}-[func]{two_sum_brute_force}
|
||||
```
|
||||
|
||||
=== "Go"
|
||||
|
@ -68,35 +68,13 @@ comments: true
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="leetcode_two_sum.js"
|
||||
function twoSumBruteForce(nums, target) {
|
||||
const n = nums.length;
|
||||
// 两层循环,时间复杂度 O(n^2)
|
||||
for (let i = 0; i < n; i++) {
|
||||
for (let j = i + 1; j < n; j++) {
|
||||
if (nums[i] + nums[j] === target) {
|
||||
return [i, j];
|
||||
}
|
||||
}
|
||||
}
|
||||
return [];
|
||||
}
|
||||
[class]{}-[func]{twoSumBruteForce}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="leetcode_two_sum.ts"
|
||||
function twoSumBruteForce(nums: number[], target: number): number[] {
|
||||
const n = nums.length;
|
||||
// 两层循环,时间复杂度 O(n^2)
|
||||
for (let i = 0; i < n; i++) {
|
||||
for (let j = i + 1; j < n; j++) {
|
||||
if (nums[i] + nums[j] === target) {
|
||||
return [i, j];
|
||||
}
|
||||
}
|
||||
}
|
||||
return [];
|
||||
};
|
||||
[class]{}-[func]{twoSumBruteForce}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
@ -174,19 +152,19 @@ comments: true
|
|||
=== "Java"
|
||||
|
||||
```java title="leetcode_two_sum.java"
|
||||
[class]{SolutionHashMap}-[func]{}
|
||||
[class]{leetcode_two_sum}-[func]{twoSumHashTable}
|
||||
```
|
||||
|
||||
=== "C++"
|
||||
|
||||
```cpp title="leetcode_two_sum.cpp"
|
||||
[class]{SolutionHashMap}-[func]{}
|
||||
[class]{}-[func]{twoSumHashTable}
|
||||
```
|
||||
|
||||
=== "Python"
|
||||
|
||||
```python title="leetcode_two_sum.py"
|
||||
[class]{SolutionHashMap}-[func]{}
|
||||
[class]{}-[func]{two_sum_hash_table}
|
||||
```
|
||||
|
||||
=== "Go"
|
||||
|
@ -209,38 +187,13 @@ comments: true
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="leetcode_two_sum.js"
|
||||
function twoSumHashTable(nums, target) {
|
||||
// 辅助哈希表,空间复杂度 O(n)
|
||||
let m = {};
|
||||
// 单层循环,时间复杂度 O(n)
|
||||
for (let i = 0; i < nums.length; i++) {
|
||||
if (m[nums[i]] !== undefined) {
|
||||
return [m[nums[i]], i];
|
||||
} else {
|
||||
m[target - nums[i]] = i;
|
||||
}
|
||||
}
|
||||
return [];
|
||||
}
|
||||
[class]{}-[func]{twoSumHashTable}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="leetcode_two_sum.ts"
|
||||
function twoSumHashTable(nums: number[], target: number): number[] {
|
||||
// 辅助哈希表,空间复杂度 O(n)
|
||||
let m: Map<number, number> = new Map();
|
||||
// 单层循环,时间复杂度 O(n)
|
||||
for (let i = 0; i < nums.length; i++) {
|
||||
let index = m.get(nums[i]);
|
||||
if (index !== undefined) {
|
||||
return [index, i];
|
||||
} else {
|
||||
m.set(target - nums[i], i);
|
||||
}
|
||||
}
|
||||
return [];
|
||||
};
|
||||
[class]{}-[func]{twoSumHashTable}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
|
|
@ -827,25 +827,13 @@ $$
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="time_complexity.js"
|
||||
/* 常数阶 */
|
||||
function constant(n) {
|
||||
let count = 0;
|
||||
const size = 100000;
|
||||
for (let i = 0; i < size; i++) count++;
|
||||
return count;
|
||||
}
|
||||
[class]{}-[func]{constant}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="time_complexity.ts"
|
||||
/* 常数阶 */
|
||||
function constant(n: number): number {
|
||||
let count = 0;
|
||||
const size = 100000;
|
||||
for (let i = 0; i < size; i++) count++;
|
||||
return count;
|
||||
}
|
||||
[class]{}-[func]{constant}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
@ -945,23 +933,13 @@ $$
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="time_complexity.js"
|
||||
/* 线性阶 */
|
||||
function linear(n) {
|
||||
let count = 0;
|
||||
for (let i = 0; i < n; i++) count++;
|
||||
return count;
|
||||
}
|
||||
[class]{}-[func]{linear}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="time_complexity.ts"
|
||||
/* 线性阶 */
|
||||
function linear(n: number): number {
|
||||
let count = 0;
|
||||
for (let i = 0; i < n; i++) count++;
|
||||
return count;
|
||||
}
|
||||
[class]{}-[func]{linear}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
@ -1058,29 +1036,13 @@ $$
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="time_complexity.js"
|
||||
/* 线性阶(遍历数组) */
|
||||
function arrayTraversal(nums) {
|
||||
let count = 0;
|
||||
// 循环次数与数组长度成正比
|
||||
for (let i = 0; i < nums.length; i++) {
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
[class]{}-[func]{arrayTraversal}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="time_complexity.ts"
|
||||
/* 线性阶(遍历数组) */
|
||||
function arrayTraversal(nums: number[]): number {
|
||||
let count = 0;
|
||||
// 循环次数与数组长度成正比
|
||||
for (let i = 0; i < nums.length; i++) {
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
[class]{}-[func]{arrayTraversal}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
@ -1182,33 +1144,13 @@ $$
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="time_complexity.js"
|
||||
/* 平方阶 */
|
||||
function quadratic(n) {
|
||||
let count = 0;
|
||||
// 循环次数与数组长度成平方关系
|
||||
for (let i = 0; i < n; i++) {
|
||||
for (let j = 0; j < n; j++) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
[class]{}-[func]{quadratic}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="time_complexity.ts"
|
||||
/* 平方阶 */
|
||||
function quadratic(n: number): number {
|
||||
let count = 0;
|
||||
// 循环次数与数组长度成平方关系
|
||||
for (let i = 0; i < n; i++) {
|
||||
for (let j = 0; j < n; j++) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
[class]{}-[func]{quadratic}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
@ -1334,47 +1276,13 @@ $$
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="time_complexity.js"
|
||||
/* 平方阶(冒泡排序) */
|
||||
function bubbleSort(nums) {
|
||||
let count = 0; // 计数器
|
||||
// 外循环:待排序元素数量为 n-1, n-2, ..., 1
|
||||
for (let i = nums.length - 1; i > 0; i--) {
|
||||
// 内循环:冒泡操作
|
||||
for (let j = 0; j < i; j++) {
|
||||
if (nums[j] > nums[j + 1]) {
|
||||
// 交换 nums[j] 与 nums[j + 1]
|
||||
let tmp = nums[j];
|
||||
nums[j] = nums[j + 1];
|
||||
nums[j + 1] = tmp;
|
||||
count += 3; // 元素交换包含 3 个单元操作
|
||||
}
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
[class]{}-[func]{bubbleSort}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="time_complexity.ts"
|
||||
/* 平方阶(冒泡排序) */
|
||||
function bubbleSort(nums: number[]): number {
|
||||
let count = 0; // 计数器
|
||||
// 外循环:待排序元素数量为 n-1, n-2, ..., 1
|
||||
for (let i = nums.length - 1; i > 0; i--) {
|
||||
// 内循环:冒泡操作
|
||||
for (let j = 0; j < i; j++) {
|
||||
if (nums[j] > nums[j + 1]) {
|
||||
// 交换 nums[j] 与 nums[j + 1]
|
||||
let tmp = nums[j];
|
||||
nums[j] = nums[j + 1];
|
||||
nums[j + 1] = tmp;
|
||||
count += 3; // 元素交换包含 3 个单元操作
|
||||
}
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
[class]{}-[func]{bubbleSort}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
@ -1525,40 +1433,13 @@ $$
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="time_complexity.js"
|
||||
/* 指数阶(循环实现) */
|
||||
function exponential(n) {
|
||||
let count = 0,
|
||||
base = 1;
|
||||
// cell 每轮一分为二,形成数列 1, 2, 4, 8, ..., 2^(n-1)
|
||||
for (let i = 0; i < n; i++) {
|
||||
for (let j = 0; j < base; j++) {
|
||||
count++;
|
||||
}
|
||||
base *= 2;
|
||||
}
|
||||
// count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1
|
||||
return count;
|
||||
}
|
||||
|
||||
[class]{}-[func]{exponential}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="time_complexity.ts"
|
||||
/* 指数阶(循环实现) */
|
||||
function exponential(n: number): number {
|
||||
let count = 0,
|
||||
base = 1;
|
||||
// cell 每轮一分为二,形成数列 1, 2, 4, 8, ..., 2^(n-1)
|
||||
for (let i = 0; i < n; i++) {
|
||||
for (let j = 0; j < base; j++) {
|
||||
count++;
|
||||
}
|
||||
base *= 2;
|
||||
}
|
||||
// count = 1 + 2 + 4 + 8 + .. + 2^(n-1) = 2^n - 1
|
||||
return count;
|
||||
}
|
||||
[class]{}-[func]{exponential}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
@ -1680,22 +1561,13 @@ $$
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="time_complexity.js"
|
||||
/* 指数阶(递归实现) */
|
||||
function expRecur(n) {
|
||||
if (n == 1) return 1;
|
||||
return expRecur(n - 1) + expRecur(n - 1) + 1;
|
||||
}
|
||||
[class]{}-[func]{expRecur}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="time_complexity.ts"
|
||||
/* 指数阶(递归实现) */
|
||||
function expRecur(n: number): number {
|
||||
if (n == 1) return 1;
|
||||
return expRecur(n - 1) + expRecur(n - 1) + 1;
|
||||
}
|
||||
|
||||
[class]{}-[func]{expRecur}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
@ -1784,29 +1656,13 @@ $$
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="time_complexity.js"
|
||||
/* 对数阶(循环实现) */
|
||||
function logarithmic(n) {
|
||||
let count = 0;
|
||||
while (n > 1) {
|
||||
n = n / 2;
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
[class]{}-[func]{logarithmic}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="time_complexity.ts"
|
||||
/* 对数阶(循环实现) */
|
||||
function logarithmic(n: number): number {
|
||||
let count = 0;
|
||||
while (n > 1) {
|
||||
n = n / 2;
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
[class]{}-[func]{logarithmic}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
@ -1910,21 +1766,13 @@ $$
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="time_complexity.js"
|
||||
/* 对数阶(递归实现) */
|
||||
function logRecur(n) {
|
||||
if (n <= 1) return 0;
|
||||
return logRecur(n / 2) + 1;
|
||||
}
|
||||
[class]{}-[func]{logRecur}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="time_complexity.ts"
|
||||
/* 对数阶(递归实现) */
|
||||
function logRecur(n: number): number {
|
||||
if (n <= 1) return 0;
|
||||
return logRecur(n / 2) + 1;
|
||||
}
|
||||
[class]{}-[func]{logRecur}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
@ -2015,29 +1863,13 @@ $$
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="time_complexity.js"
|
||||
/* 线性对数阶 */
|
||||
function linearLogRecur(n) {
|
||||
if (n <= 1) return 1;
|
||||
let count = linearLogRecur(n / 2) + linearLogRecur(n / 2);
|
||||
for (let i = 0; i < n; i++) {
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
[class]{}-[func]{linearLogRecur}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="time_complexity.ts"
|
||||
/* 线性对数阶 */
|
||||
function linearLogRecur(n: number): number {
|
||||
if (n <= 1) return 1;
|
||||
let count = linearLogRecur(n / 2) + linearLogRecur(n / 2);
|
||||
for (let i = 0; i < n; i++) {
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
[class]{}-[func]{linearLogRecur}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
@ -2157,31 +1989,13 @@ $$
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="time_complexity.js"
|
||||
/* 阶乘阶(递归实现) */
|
||||
function factorialRecur(n) {
|
||||
if (n == 0) return 1;
|
||||
let count = 0;
|
||||
// 从 1 个分裂出 n 个
|
||||
for (let i = 0; i < n; i++) {
|
||||
count += factorialRecur(n - 1);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
[class]{}-[func]{factorialRecur}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="time_complexity.ts"
|
||||
/* 阶乘阶(递归实现) */
|
||||
function factorialRecur(n: number): number {
|
||||
if (n == 0) return 1;
|
||||
let count = 0;
|
||||
// 从 1 个分裂出 n 个
|
||||
for (let i = 0; i < n; i++) {
|
||||
count += factorialRecur(n - 1);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
[class]{}-[func]{factorialRecur}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
|
|
@ -491,100 +491,17 @@ $$
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="array_hash_map.js"
|
||||
/* 键值对 Number -> String */
|
||||
class Entry {
|
||||
constructor(key, val) {
|
||||
this.key = key;
|
||||
this.val = val;
|
||||
}
|
||||
}
|
||||
|
||||
/* 基于数组简易实现的哈希表 */
|
||||
class ArrayHashMap {
|
||||
#bucket;
|
||||
constructor() {
|
||||
// 初始化一个长度为 100 的桶(数组)
|
||||
this.#bucket = new Array(100).fill(null);
|
||||
}
|
||||
|
||||
/* 哈希函数 */
|
||||
#hashFunc(key) {
|
||||
return key % 100;
|
||||
}
|
||||
|
||||
/* 查询操作 */
|
||||
get(key) {
|
||||
let index = this.#hashFunc(key);
|
||||
let entry = this.#bucket[index];
|
||||
if (entry === null) return null;
|
||||
return entry.val;
|
||||
}
|
||||
|
||||
/* 添加操作 */
|
||||
set(key, val) {
|
||||
let index = this.#hashFunc(key);
|
||||
this.#bucket[index] = new Entry(key, val);
|
||||
}
|
||||
|
||||
/* 删除操作 */
|
||||
delete(key) {
|
||||
let index = this.#hashFunc(key);
|
||||
// 置为 null ,代表删除
|
||||
this.#bucket[index] = null;
|
||||
}
|
||||
}
|
||||
[class]{Entry}-[func]{}
|
||||
|
||||
[class]{ArrayHashMap}-[func]{}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="array_hash_map.ts"
|
||||
/* 键值对 Number -> String */
|
||||
class Entry {
|
||||
public key: number;
|
||||
public val: string;
|
||||
|
||||
constructor(key: number, val: string) {
|
||||
this.key = key;
|
||||
this.val = val;
|
||||
}
|
||||
}
|
||||
|
||||
/* 基于数组简易实现的哈希表 */
|
||||
class ArrayHashMap {
|
||||
|
||||
private readonly bucket: (Entry | null)[];
|
||||
|
||||
constructor() {
|
||||
// 初始化一个长度为 100 的桶(数组)
|
||||
this.bucket = (new Array(100)).fill(null);
|
||||
}
|
||||
|
||||
/* 哈希函数 */
|
||||
private hashFunc(key: number): number {
|
||||
return key % 100;
|
||||
}
|
||||
|
||||
/* 查询操作 */
|
||||
public get(key: number): string | null {
|
||||
let index = this.hashFunc(key);
|
||||
let entry = this.bucket[index];
|
||||
if (entry === null) return null;
|
||||
return entry.val;
|
||||
}
|
||||
|
||||
/* 添加操作 */
|
||||
public set(key: number, val: string) {
|
||||
let index = this.hashFunc(key);
|
||||
this.bucket[index] = new Entry(key, val);
|
||||
}
|
||||
|
||||
/* 删除操作 */
|
||||
public delete(key: number) {
|
||||
let index = this.hashFunc(key);
|
||||
// 置为 null ,代表删除
|
||||
this.bucket[index] = null;
|
||||
}
|
||||
}
|
||||
[class]{Entry}-[func]{}
|
||||
|
||||
[class]{ArrayHashMap}-[func]{}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
|
|
@ -270,23 +270,11 @@ comments: true
|
|||
=== "C++"
|
||||
|
||||
```cpp title="my_heap.cpp"
|
||||
// 使用动态数组,这样无需考虑扩容问题
|
||||
vector<int> maxHeap;
|
||||
[class]{MaxHeap}-[func]{left}
|
||||
|
||||
/* 获取左子结点索引 */
|
||||
int left(int i) {
|
||||
return 2 * i + 1;
|
||||
}
|
||||
[class]{MaxHeap}-[func]{right}
|
||||
|
||||
/* 获取右子结点索引 */
|
||||
int right(int i) {
|
||||
return 2 * i + 2;
|
||||
}
|
||||
|
||||
/* 获取父结点索引 */
|
||||
int parent(int i) {
|
||||
return (i - 1) / 2; // 向下取整
|
||||
}
|
||||
[class]{MaxHeap}-[func]{parent}
|
||||
```
|
||||
|
||||
=== "Python"
|
||||
|
@ -330,62 +318,21 @@ comments: true
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="my_heap.js"
|
||||
#maxHeap;
|
||||
[class]{MaxHeap}-[func]{#left}
|
||||
|
||||
/* 构造函数,建立空堆或根据输入列表建堆 */
|
||||
constructor(nums) {
|
||||
// 将列表元素原封不动添加进堆
|
||||
this.#maxHeap = nums === undefined ? [] : [...nums];
|
||||
// 堆化除叶结点以外的其他所有结点
|
||||
for (let i = this.#parent(this.size() - 1); i >= 0; i--) {
|
||||
this.#siftDown(i);
|
||||
}
|
||||
}
|
||||
[class]{MaxHeap}-[func]{#right}
|
||||
|
||||
/* 获取左子结点索引 */
|
||||
#left(i) {
|
||||
return 2 * i + 1;
|
||||
}
|
||||
|
||||
/* 获取右子结点索引 */
|
||||
#right(i) {
|
||||
return 2 * i + 2;
|
||||
}
|
||||
|
||||
/* 获取父结点索引 */
|
||||
#parent(i) {
|
||||
return Math.floor((i - 1) / 2); // 向下整除
|
||||
}
|
||||
[class]{MaxHeap}-[func]{#parent}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="my_heap.ts"
|
||||
private maxHeap: number[];
|
||||
/* 构造函数,建立空堆或根据输入列表建堆 */
|
||||
constructor(nums?: number[]) {
|
||||
// 将列表元素原封不动添加进堆
|
||||
this.maxHeap = nums === undefined ? [] : [...nums];
|
||||
// 堆化除叶结点以外的其他所有结点
|
||||
for (let i = this.parent(this.size() - 1); i >= 0; i--) {
|
||||
this.siftDown(i);
|
||||
}
|
||||
}
|
||||
[class]{MaxHeap}-[func]{left}
|
||||
|
||||
/* 获取左子结点索引 */
|
||||
private left(i: number): number {
|
||||
return 2 * i + 1;
|
||||
}
|
||||
[class]{MaxHeap}-[func]{right}
|
||||
|
||||
/* 获取右子结点索引 */
|
||||
private right(i: number): number {
|
||||
return 2 * i + 2;
|
||||
}
|
||||
|
||||
/* 获取父结点索引 */
|
||||
private parent(i: number): number {
|
||||
return Math.floor((i - 1) / 2); // 向下整除
|
||||
}
|
||||
[class]{MaxHeap}-[func]{parent}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
@ -466,19 +413,13 @@ comments: true
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="my_heap.js"
|
||||
/* 访问堆顶元素 */
|
||||
peek() {
|
||||
return this.#maxHeap[0];
|
||||
}
|
||||
[class]{MaxHeap}-[func]{peek}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="my_heap.ts"
|
||||
/* 访问堆顶元素 */
|
||||
public peek(): number {
|
||||
return this.maxHeap[0];
|
||||
}
|
||||
[class]{MaxHeap}-[func]{peek}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
@ -587,53 +528,17 @@ comments: true
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="my_heap.js"
|
||||
/* 元素入堆 */
|
||||
push(val) {
|
||||
// 添加结点
|
||||
this.#maxHeap.push(val);
|
||||
// 从底至顶堆化
|
||||
this.#siftUp(this.size() - 1);
|
||||
}
|
||||
[class]{MaxHeap}-[func]{push}
|
||||
|
||||
/* 从结点 i 开始,从底至顶堆化 */
|
||||
#siftUp(i) {
|
||||
while (true) {
|
||||
// 获取结点 i 的父结点
|
||||
const p = this.#parent(i);
|
||||
// 当“越过根结点”或“结点无需修复”时,结束堆化
|
||||
if (p < 0 || this.#maxHeap[i] <= this.#maxHeap[p]) break;
|
||||
// 交换两结点
|
||||
this.#swap(i, p);
|
||||
// 循环向上堆化
|
||||
i = p;
|
||||
}
|
||||
}
|
||||
[class]{MaxHeap}-[func]{#siftUp}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="my_heap.ts"
|
||||
/* 元素入堆 */
|
||||
public push(val: number): void {
|
||||
// 添加结点
|
||||
this.maxHeap.push(val);
|
||||
// 从底至顶堆化
|
||||
this.siftUp(this.size() - 1);
|
||||
}
|
||||
[class]{MaxHeap}-[func]{push}
|
||||
|
||||
/* 从结点 i 开始,从底至顶堆化 */
|
||||
private siftUp(i: number): void {
|
||||
while (true) {
|
||||
// 获取结点 i 的父结点
|
||||
const p = this.parent(i);
|
||||
// 当“越过根结点”或“结点无需修复”时,结束堆化
|
||||
if (p < 0 || this.maxHeap[i] <= this.maxHeap[p]) break;
|
||||
// 交换两结点
|
||||
this.swap(i, p);
|
||||
// 循环向上堆化
|
||||
i = p;
|
||||
}
|
||||
}
|
||||
[class]{MaxHeap}-[func]{siftUp}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
@ -795,72 +700,17 @@ comments: true
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="my_heap.js"
|
||||
/* 元素出堆 */
|
||||
poll() {
|
||||
// 判空处理
|
||||
if (this.isEmpty()) throw new Error("堆为空");
|
||||
// 交换根结点与最右叶结点(即交换首元素与尾元素)
|
||||
this.#swap(0, this.size() - 1);
|
||||
// 删除结点
|
||||
const val = this.#maxHeap.pop();
|
||||
// 从顶至底堆化
|
||||
this.#siftDown(0);
|
||||
// 返回堆顶元素
|
||||
return val;
|
||||
}
|
||||
[class]{MaxHeap}-[func]{poll}
|
||||
|
||||
/* 从结点 i 开始,从顶至底堆化 */
|
||||
#siftDown(i) {
|
||||
while (true) {
|
||||
// 判断结点 i, l, r 中值最大的结点,记为 ma
|
||||
const l = this.#left(i),
|
||||
r = this.#right(i);
|
||||
let ma = i;
|
||||
if (l < this.size() && this.#maxHeap[l] > this.#maxHeap[ma]) ma = l;
|
||||
if (r < this.size() && this.#maxHeap[r] > this.#maxHeap[ma]) ma = r;
|
||||
// 若结点 i 最大或索引 l, r 越界,则无需继续堆化,跳出
|
||||
if (ma == i) break;
|
||||
// 交换两结点
|
||||
this.#swap(i, ma);
|
||||
// 循环向下堆化
|
||||
i = ma;
|
||||
}
|
||||
}
|
||||
[class]{MaxHeap}-[func]{#siftDown}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="my_heap.ts"
|
||||
/* 元素出堆 */
|
||||
public poll(): number {
|
||||
// 判空处理
|
||||
if (this.isEmpty()) throw new RangeError("Heap is empty.");
|
||||
// 交换根结点与最右叶结点(即交换首元素与尾元素)
|
||||
this.swap(0, this.size() - 1);
|
||||
// 删除结点
|
||||
const val = this.maxHeap.pop();
|
||||
// 从顶至底堆化
|
||||
this.siftDown(0);
|
||||
// 返回堆顶元素
|
||||
return val;
|
||||
}
|
||||
[class]{MaxHeap}-[func]{poll}
|
||||
|
||||
/* 从结点 i 开始,从顶至底堆化 */
|
||||
private siftDown(i: number): void {
|
||||
while (true) {
|
||||
// 判断结点 i, l, r 中值最大的结点,记为 ma
|
||||
const l = this.left(i), r = this.right(i);
|
||||
let ma = i;
|
||||
if (l < this.size() && this.maxHeap[l] > this.maxHeap[ma]) ma = l;
|
||||
if (r < this.size() && this.maxHeap[r] > this.maxHeap[ma]) ma = r;
|
||||
// 若结点 i 最大或索引 l, r 越界,则无需继续堆化,跳出
|
||||
if (ma == i) break;
|
||||
// 交换两结点
|
||||
this.swap(i, ma);
|
||||
// 循环向下堆化
|
||||
i = ma;
|
||||
}
|
||||
}
|
||||
[class]{MaxHeap}-[func]{siftDown}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
@ -968,29 +818,13 @@ comments: true
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="my_heap.js"
|
||||
/* 构造函数,建立空堆或根据输入列表建堆 */
|
||||
constructor(nums) {
|
||||
// 将列表元素原封不动添加进堆
|
||||
this.#maxHeap = nums === undefined ? [] : [...nums];
|
||||
// 堆化除叶结点以外的其他所有结点
|
||||
for (let i = this.#parent(this.size() - 1); i >= 0; i--) {
|
||||
this.#siftDown(i);
|
||||
}
|
||||
}
|
||||
[class]{MaxHeap}-[func]{constructor}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="my_heap.ts"
|
||||
/* 构造函数,建立空堆或根据输入列表建堆 */
|
||||
constructor(nums?: number[]) {
|
||||
// 将列表元素原封不动添加进堆
|
||||
this.maxHeap = nums === undefined ? [] : [...nums];
|
||||
// 堆化除叶结点以外的其他所有结点
|
||||
for (let i = this.parent(this.size() - 1); i >= 0; i--) {
|
||||
this.siftDown(i);
|
||||
}
|
||||
}
|
||||
[class]{MaxHeap}-[func]{constructor}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
|
|
@ -95,45 +95,13 @@ $$
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="binary_search.js"
|
||||
/* 二分查找(双闭区间) */
|
||||
function binarySearch(nums, target) {
|
||||
// 初始化双闭区间 [0, n-1] ,即 i, j 分别指向数组首元素、尾元素
|
||||
let i = 0, j = nums.length - 1;
|
||||
// 循环,当搜索区间为空时跳出(当 i > j 时为空)
|
||||
while (i <= j) {
|
||||
let m = parseInt((i + j) / 2); // 计算中点索引 m ,在 JS 中需使用 parseInt 函数取整
|
||||
if (nums[m] < target) // 此情况说明 target 在区间 [m+1, j] 中
|
||||
i = m + 1;
|
||||
else if (nums[m] > target) // 此情况说明 target 在区间 [i, m-1] 中
|
||||
j = m - 1;
|
||||
else
|
||||
return m; // 找到目标元素,返回其索引
|
||||
}
|
||||
// 未找到目标元素,返回 -1
|
||||
return -1;
|
||||
}
|
||||
[class]{}-[func]{binarySearch}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="binary_search.ts"
|
||||
/* 二分查找(双闭区间) */
|
||||
const binarySearch = function (nums: number[], target: number): number {
|
||||
// 初始化双闭区间 [0, n-1] ,即 i, j 分别指向数组首元素、尾元素
|
||||
let i = 0, j = nums.length - 1;
|
||||
// 循环,当搜索区间为空时跳出(当 i > j 时为空)
|
||||
while (i <= j) {
|
||||
const m = Math.floor(i + (j - i) / 2); // 计算中点索引 m
|
||||
if (nums[m] < target) { // 此情况说明 target 在区间 [m+1, j] 中
|
||||
i = m + 1;
|
||||
} else if (nums[m] > target) { // 此情况说明 target 在区间 [i, m-1] 中
|
||||
j = m - 1;
|
||||
} else { // 找到目标元素,返回其索引
|
||||
return m;
|
||||
}
|
||||
}
|
||||
return -1; // 未找到目标元素,返回 -1
|
||||
}
|
||||
[class]{}-[func]{binarySearch}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
@ -244,45 +212,13 @@ $$
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="binary_search.js"
|
||||
/* 二分查找(左闭右开) */
|
||||
function binarySearch1(nums, target) {
|
||||
// 初始化左闭右开 [0, n) ,即 i, j 分别指向数组首元素、尾元素+1
|
||||
let i = 0, j = nums.length;
|
||||
// 循环,当搜索区间为空时跳出(当 i = j 时为空)
|
||||
while (i < j) {
|
||||
let m = parseInt((i + j) / 2); // 计算中点索引 m ,在 JS 中需使用 parseInt 函数取整
|
||||
if (nums[m] < target) // 此情况说明 target 在区间 [m+1, j) 中
|
||||
i = m + 1;
|
||||
else if (nums[m] > target) // 此情况说明 target 在区间 [i, m) 中
|
||||
j = m;
|
||||
else // 找到目标元素,返回其索引
|
||||
return m;
|
||||
}
|
||||
// 未找到目标元素,返回 -1
|
||||
return -1;
|
||||
}
|
||||
[class]{}-[func]{binarySearch1}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="binary_search.ts"
|
||||
/* 二分查找(左闭右开) */
|
||||
const binarySearch1 = function (nums: number[], target: number): number {
|
||||
// 初始化左闭右开 [0, n) ,即 i, j 分别指向数组首元素、尾元素+1
|
||||
let i = 0, j = nums.length;
|
||||
// 循环,当搜索区间为空时跳出(当 i = j 时为空)
|
||||
while (i < j) {
|
||||
const m = Math.floor(i + (j - i) / 2); // 计算中点索引 m
|
||||
if (nums[m] < target) { // 此情况说明 target 在区间 [m+1, j) 中
|
||||
i = m + 1;
|
||||
} else if (nums[m] > target) { // 此情况说明 target 在区间 [i, m) 中
|
||||
j = m;
|
||||
} else { // 找到目标元素,返回其索引
|
||||
return m;
|
||||
}
|
||||
}
|
||||
return -1; // 未找到目标元素,返回 -1
|
||||
}
|
||||
[class]{}-[func]{binarySearch1}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
|
|
@ -52,23 +52,13 @@ comments: true
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="hashing_search.js"
|
||||
/* 哈希查找(数组) */
|
||||
function hashingSearchArray(map, target) {
|
||||
// 哈希表的 key: 目标元素,value: 索引
|
||||
// 若哈希表中无此 key ,返回 -1
|
||||
return map.has(target) ? map.get(target) : -1;
|
||||
}
|
||||
[class]{}-[func]{hashingSearchArray}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="hashing_search.ts"
|
||||
/* 哈希查找(数组) */
|
||||
function hashingSearchArray(map: Map<number, number>, target: number): number {
|
||||
// 哈希表的 key: 目标元素,value: 索引
|
||||
// 若哈希表中无此 key ,返回 -1
|
||||
return map.has(target) ? map.get(target) as number : -1;
|
||||
}
|
||||
[class]{}-[func]{hashingSearchArray}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
@ -146,23 +136,13 @@ comments: true
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="hashing_search.js"
|
||||
/* 哈希查找(链表) */
|
||||
function hashingSearchLinkedList(map, target) {
|
||||
// 哈希表的 key: 目标结点值,value: 结点对象
|
||||
// 若哈希表中无此 key ,返回 null
|
||||
return map.has(target) ? map.get(target) : null;
|
||||
}
|
||||
[class]{}-[func]{hashingSearchLinkedList}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="hashing_search.ts"
|
||||
/* 哈希查找(链表) */
|
||||
function hashingSearchLinkedList(map: Map<number, ListNode>, target: number): ListNode | null {
|
||||
// 哈希表的 key: 目标结点值,value: 结点对象
|
||||
// 若哈希表中无此 key ,返回 null
|
||||
return map.has(target) ? map.get(target) as ListNode : null;
|
||||
}
|
||||
[class]{}-[func]{hashingSearchLinkedList}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
|
|
@ -50,36 +50,13 @@ comments: true
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="linear_search.js"
|
||||
/* 线性查找(数组) */
|
||||
function linearSearchArray(nums, target) {
|
||||
// 遍历数组
|
||||
for (let i = 0; i < nums.length; i++) {
|
||||
// 找到目标元素,返回其索引
|
||||
if (nums[i] === target) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
// 未找到目标元素,返回 -1
|
||||
return -1;
|
||||
}
|
||||
|
||||
[class]{}-[func]{linearSearchArray}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="linear_search.ts"
|
||||
/* 线性查找(数组)*/
|
||||
function linearSearchArray(nums: number[], target: number): number {
|
||||
// 遍历数组
|
||||
for (let i = 0; i < nums.length; i++) {
|
||||
// 找到目标元素,返回其索引
|
||||
if (nums[i] === target) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
// 未找到目标元素,返回 -1
|
||||
return -1;
|
||||
}
|
||||
[class]{}-[func]{linearSearchArray}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
@ -171,37 +148,13 @@ comments: true
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="linear_search.js"
|
||||
/* 线性查找(链表)*/
|
||||
function linearSearchLinkedList(head, target) {
|
||||
// 遍历链表
|
||||
while(head) {
|
||||
// 找到目标结点,返回之
|
||||
if(head.val === target) {
|
||||
return head;
|
||||
}
|
||||
head = head.next;
|
||||
}
|
||||
// 未找到目标结点,返回 null
|
||||
return null;
|
||||
}
|
||||
[class]{}-[func]{linearSearchLinkedList}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="linear_search.ts"
|
||||
/* 线性查找(链表)*/
|
||||
function linearSearchLinkedList(head: ListNode | null, target: number): ListNode | null {
|
||||
// 遍历链表
|
||||
while (head) {
|
||||
// 找到目标结点,返回之
|
||||
if (head.val === target) {
|
||||
return head;
|
||||
}
|
||||
head = head.next;
|
||||
}
|
||||
// 未找到目标结点,返回 null
|
||||
return null;
|
||||
}
|
||||
[class]{}-[func]{linearSearchLinkedList}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
|
|
@ -86,41 +86,13 @@ comments: true
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="bubble_sort.js"
|
||||
/* 冒泡排序 */
|
||||
function bubbleSort(nums) {
|
||||
// 外循环:待排序元素数量为 n-1, n-2, ..., 1
|
||||
for (let i = nums.length - 1; i > 0; i--) {
|
||||
// 内循环:冒泡操作
|
||||
for (let j = 0; j < i; j++) {
|
||||
if (nums[j] > nums[j + 1]) {
|
||||
// 交换 nums[j] 与 nums[j + 1]
|
||||
let tmp = nums[j];
|
||||
nums[j] = nums[j + 1];
|
||||
nums[j + 1] = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
[class]{}-[func]{bubbleSort}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="bubble_sort.ts"
|
||||
/* 冒泡排序 */
|
||||
function bubbleSort(nums: number[]): void {
|
||||
// 外循环:待排序元素数量为 n-1, n-2, ..., 1
|
||||
for (let i = nums.length - 1; i > 0; i--) {
|
||||
// 内循环:冒泡操作
|
||||
for (let j = 0; j < i; j++) {
|
||||
if (nums[j] > nums[j + 1]) {
|
||||
// 交换 nums[j] 与 nums[j + 1]
|
||||
let tmp = nums[j];
|
||||
nums[j] = nums[j + 1];
|
||||
nums[j + 1] = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
[class]{}-[func]{bubbleSort}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
@ -257,47 +229,13 @@ comments: true
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="bubble_sort.js"
|
||||
/* 冒泡排序(标志优化)*/
|
||||
function bubbleSortWithFlag(nums) {
|
||||
// 外循环:待排序元素数量为 n-1, n-2, ..., 1
|
||||
for (let i = nums.length - 1; i > 0; i--) {
|
||||
let flag = false; // 初始化标志位
|
||||
// 内循环:冒泡操作
|
||||
for (let j = 0; j < i; j++) {
|
||||
if (nums[j] > nums[j + 1]) {
|
||||
// 交换 nums[j] 与 nums[j + 1]
|
||||
let tmp = nums[j];
|
||||
nums[j] = nums[j + 1];
|
||||
nums[j + 1] = tmp;
|
||||
flag = true; // 记录交换元素
|
||||
}
|
||||
}
|
||||
if (!flag) break; // 此轮冒泡未交换任何元素,直接跳出
|
||||
}
|
||||
}
|
||||
[class]{}-[func]{bubbleSortWithFlag}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="bubble_sort.ts"
|
||||
/* 冒泡排序(标志优化)*/
|
||||
function bubbleSortWithFlag(nums: number[]): void {
|
||||
// 外循环:待排序元素数量为 n-1, n-2, ..., 1
|
||||
for (let i = nums.length - 1; i > 0; i--) {
|
||||
let flag = false; // 初始化标志位
|
||||
// 内循环:冒泡操作
|
||||
for (let j = 0; j < i; j++) {
|
||||
if (nums[j] > nums[j + 1]) {
|
||||
// 交换 nums[j] 与 nums[j + 1]
|
||||
let tmp = nums[j];
|
||||
nums[j] = nums[j + 1];
|
||||
nums[j + 1] = tmp;
|
||||
flag = true; // 记录交换元素
|
||||
}
|
||||
}
|
||||
if (!flag) break; // 此轮冒泡未交换任何元素,直接跳出
|
||||
}
|
||||
}
|
||||
[class]{}-[func]{bubbleSortWithFlag}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
|
|
@ -64,38 +64,13 @@ comments: true
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="insertion_sort.js"
|
||||
/* 插入排序 */
|
||||
function insertionSort(nums) {
|
||||
// 外循环:base = nums[1], nums[2], ..., nums[n-1]
|
||||
for (let i = 1; i < nums.length; i++) {
|
||||
let base = nums[i], j = i - 1;
|
||||
// 内循环:将 base 插入到左边的正确位置
|
||||
while (j >= 0 && nums[j] > base) {
|
||||
nums[j + 1] = nums[j]; // 1. 将 nums[j] 向右移动一位
|
||||
j--;
|
||||
}
|
||||
nums[j + 1] = base; // 2. 将 base 赋值到正确位置
|
||||
}
|
||||
}
|
||||
[class]{}-[func]{insertionSort}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="insertion_sort.ts"
|
||||
/* 插入排序 */
|
||||
function insertionSort(nums: number[]): void {
|
||||
// 外循环:base = nums[1], nums[2], ..., nums[n-1]
|
||||
for (let i = 1; i < nums.length; i++) {
|
||||
const base = nums[i];
|
||||
let j = i - 1;
|
||||
// 内循环:将 base 插入到左边的正确位置
|
||||
while (j >= 0 && nums[j] > base) {
|
||||
nums[j + 1] = nums[j]; // 1. 将 nums[j] 向右移动一位
|
||||
j--;
|
||||
}
|
||||
nums[j + 1] = base; // 2. 将 base 赋值到正确位置
|
||||
}
|
||||
}
|
||||
[class]{}-[func]{insertionSort}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
|
|
@ -108,7 +108,7 @@ comments: true
|
|||
|
||||
=== "JavaScript"
|
||||
|
||||
``` js title="quick_sort.js"
|
||||
```javascript title="quick_sort.js"
|
||||
/* 元素交换 */
|
||||
function swap(nums, i, j) {
|
||||
let tmp = nums[i];
|
||||
|
@ -288,33 +288,13 @@ comments: true
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="quick_sort.js"
|
||||
/* 快速排序 */
|
||||
function quickSort(nums, left, right) {
|
||||
// 子数组长度为 1 时终止递归
|
||||
if (left >= right) return;
|
||||
// 哨兵划分
|
||||
const pivot = partition(nums, left, right);
|
||||
// 递归左子数组、右子数组
|
||||
quickSort(nums, left, pivot - 1);
|
||||
quickSort(nums, pivot + 1, right);
|
||||
}
|
||||
[class]{QuickSort}-[func]{quickSort}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="quick_sort.ts"
|
||||
/* 快速排序 */
|
||||
function quickSort(nums: number[], left: number, right: number): void {
|
||||
// 子数组长度为 1 时终止递归
|
||||
if (left >= right) {
|
||||
return;
|
||||
}
|
||||
// 哨兵划分
|
||||
const pivot = partition(nums, left, right);
|
||||
// 递归左子数组、右子数组
|
||||
quickSort(nums, left, pivot - 1);
|
||||
quickSort(nums, pivot + 1, right);
|
||||
}
|
||||
[class]{QuickSort}-[func]{quickSort}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
@ -445,53 +425,17 @@ comments: true
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="quick_sort.js"
|
||||
/* 选取三个元素的中位数 */
|
||||
function medianThree(nums, left, mid, right) {
|
||||
// 使用了异或操作来简化代码
|
||||
// 异或规则为 0 ^ 0 = 1 ^ 1 = 0, 0 ^ 1 = 1 ^ 0 = 1
|
||||
if ((nums[left] < nums[mid]) ^ (nums[left] < nums[right]))
|
||||
return left;
|
||||
else if ((nums[mid] < nums[left]) ^ (nums[mid] < nums[right]))
|
||||
return mid;
|
||||
else
|
||||
return right;
|
||||
}
|
||||
|
||||
/* 哨兵划分(三数取中值) */
|
||||
function partition(nums, left, right) {
|
||||
// 选取三个候选元素的中位数
|
||||
let med = medianThree(nums, left, Math.floor((left + right) / 2), right);
|
||||
// 将中位数交换至数组最左端
|
||||
swap(nums, left, med);
|
||||
// 以 nums[left] 作为基准数
|
||||
// 下同省略...
|
||||
}
|
||||
[class]{QuickSortMedian}-[func]{medianThree}
|
||||
|
||||
[class]{QuickSortMedian}-[func]{partition}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="quick_sort.ts"
|
||||
/* 选取三个元素的中位数 */
|
||||
function medianThree(nums: number[], left: number, mid: number, right: number): number {
|
||||
// 使用了异或操作来简化代码
|
||||
// 异或规则为 0 ^ 0 = 1 ^ 1 = 0, 0 ^ 1 = 1 ^ 0 = 1
|
||||
if (Number(nums[left] < nums[mid]) ^ Number(nums[left] < nums[right])) {
|
||||
return left;
|
||||
} else if (Number(nums[mid] < nums[left]) ^ Number(nums[mid] < nums[right])) {
|
||||
return mid;
|
||||
} else {
|
||||
return right;
|
||||
}
|
||||
}
|
||||
[class]{QuickSortMedian}-[func]{medianThree}
|
||||
|
||||
/* 哨兵划分(三数取中值) */
|
||||
function partition(nums: number[], left: number, right: number): number {
|
||||
// 选取三个候选元素的中位数
|
||||
let med = medianThree(nums, left, Math.floor((left + right) / 2), right);
|
||||
// 将中位数交换至数组最左端
|
||||
swap(nums, left, med);
|
||||
// 以 nums[left] 作为基准数
|
||||
// 下同省略...
|
||||
[class]{QuickSortMedian}-[func]{partition}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
@ -607,43 +551,13 @@ comments: true
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="quick_sort.js"
|
||||
/* 快速排序(尾递归优化) */
|
||||
function quickSort(nums, left, right) {
|
||||
// 子数组长度为 1 时终止
|
||||
while (left < right) {
|
||||
// 哨兵划分操作
|
||||
let pivot = partition(nums, left, right);
|
||||
// 对两个子数组中较短的那个执行快排
|
||||
if (pivot - left < right - pivot) {
|
||||
quickSort(nums, left, pivot - 1); // 递归排序左子数组
|
||||
left = pivot + 1; // 剩余待排序区间为 [pivot + 1, right]
|
||||
} else {
|
||||
quickSort(nums, pivot + 1, right); // 递归排序右子数组
|
||||
right = pivot - 1; // 剩余待排序区间为 [left, pivot - 1]
|
||||
}
|
||||
}
|
||||
}
|
||||
[class]{QuickSortTailCall}-[func]{quickSort}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="quick_sort.ts"
|
||||
/* 快速排序(尾递归优化) */
|
||||
function quickSort(nums: number[], left: number, right: number): void {
|
||||
// 子数组长度为 1 时终止
|
||||
while (left < right) {
|
||||
// 哨兵划分操作
|
||||
let pivot = partition(nums, left, right);
|
||||
// 对两个子数组中较短的那个执行快排
|
||||
if (pivot - left < right - pivot) {
|
||||
quickSort(nums, left, pivot - 1); // 递归排序左子数组
|
||||
left = pivot + 1; // 剩余待排序区间为 [pivot + 1, right]
|
||||
} else {
|
||||
quickSort(nums, pivot + 1, right); // 递归排序右子数组
|
||||
right = pivot - 1; // 剩余待排序区间为 [left, pivot - 1]
|
||||
}
|
||||
}
|
||||
}
|
||||
[class]{QuickSortTailCall}-[func]{quickSort}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
|
|
@ -353,107 +353,13 @@ comments: true
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="linkedlist_queue.js"
|
||||
/* 基于链表实现的队列 */
|
||||
class LinkedListQueue {
|
||||
#front; // 头结点 #front
|
||||
#rear; // 尾结点 #rear
|
||||
#queSize = 0;
|
||||
constructor() {
|
||||
this.#front = null;
|
||||
this.#rear = null;
|
||||
}
|
||||
/* 获取队列的长度 */
|
||||
get size() {
|
||||
return this.#queSize;
|
||||
}
|
||||
/* 判断队列是否为空 */
|
||||
isEmpty() {
|
||||
return this.size === 0;
|
||||
}
|
||||
/* 入队 */
|
||||
push(num) {
|
||||
// 尾结点后添加 num
|
||||
const node = new ListNode(num);
|
||||
// 如果队列为空,则令头、尾结点都指向该结点
|
||||
if (!this.#front) {
|
||||
this.#front = node;
|
||||
this.#rear = node;
|
||||
// 如果队列不为空,则将该结点添加到尾结点后
|
||||
} else {
|
||||
this.#rear.next = node;
|
||||
this.#rear = node;
|
||||
}
|
||||
this.#queSize++;
|
||||
}
|
||||
/* 出队 */
|
||||
poll() {
|
||||
const num = this.peek();
|
||||
// 删除头结点
|
||||
this.#front = this.#front.next;
|
||||
this.#queSize--;
|
||||
return num;
|
||||
}
|
||||
/* 访问队首元素 */
|
||||
peek() {
|
||||
if (this.size === 0)
|
||||
throw new Error("队列为空");
|
||||
return this.#front.val;
|
||||
}
|
||||
}
|
||||
[class]{LinkedListQueue}-[func]{}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="linkedlist_queue.ts"
|
||||
/* 基于链表实现的队列 */
|
||||
class LinkedListQueue {
|
||||
private front: ListNode | null; // 头结点 front
|
||||
private rear: ListNode | null; // 尾结点 rear
|
||||
private queSize: number = 0;
|
||||
constructor() {
|
||||
this.front = null;
|
||||
this.rear = null;
|
||||
}
|
||||
/* 获取队列的长度 */
|
||||
get size(): number {
|
||||
return this.queSize;
|
||||
}
|
||||
/* 判断队列是否为空 */
|
||||
isEmpty(): boolean {
|
||||
return this.size === 0;
|
||||
}
|
||||
/* 入队 */
|
||||
push(num: number): void {
|
||||
// 尾结点后添加 num
|
||||
const node = new ListNode(num);
|
||||
// 如果队列为空,则令头、尾结点都指向该结点
|
||||
if (!this.front) {
|
||||
this.front = node;
|
||||
this.rear = node;
|
||||
// 如果队列不为空,则将该结点添加到尾结点后
|
||||
} else {
|
||||
this.rear!.next = node;
|
||||
this.rear = node;
|
||||
}
|
||||
this.queSize++;
|
||||
}
|
||||
/* 出队 */
|
||||
poll(): number {
|
||||
const num = this.peek();
|
||||
if (!this.front)
|
||||
throw new Error("队列为空")
|
||||
// 删除头结点
|
||||
this.front = this.front.next;
|
||||
this.queSize--;
|
||||
return num;
|
||||
}
|
||||
/* 访问队首元素 */
|
||||
peek(): number {
|
||||
if (this.size === 0)
|
||||
throw new Error("队列为空");
|
||||
return this.front!.val;
|
||||
}
|
||||
}
|
||||
[class]{LinkedListQueue}-[func]{}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
@ -698,122 +604,13 @@ comments: true
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="array_queue.js"
|
||||
/* 基于环形数组实现的队列 */
|
||||
class ArrayQueue {
|
||||
#nums; // 用于存储队列元素的数组
|
||||
#front = 0; // 队首指针,指向队首元素
|
||||
#queSize = 0; // 队列长度
|
||||
|
||||
constructor(capacity) {
|
||||
this.#nums = new Array(capacity);
|
||||
}
|
||||
|
||||
/* 获取队列的容量 */
|
||||
get capacity() {
|
||||
return this.#nums.length;
|
||||
}
|
||||
|
||||
/* 获取队列的长度 */
|
||||
get size() {
|
||||
return this.#queSize;
|
||||
}
|
||||
|
||||
/* 判断队列是否为空 */
|
||||
empty() {
|
||||
return this.#queSize == 0;
|
||||
}
|
||||
|
||||
/* 入队 */
|
||||
push(num) {
|
||||
if (this.size == this.capacity) {
|
||||
console.log("队列已满");
|
||||
return;
|
||||
}
|
||||
// 计算尾指针,指向队尾索引 + 1
|
||||
// 通过取余操作,实现 rear 越过数组尾部后回到头部
|
||||
const rear = (this.#front + this.size) % this.capacity;
|
||||
// 尾结点后添加 num
|
||||
this.#nums[rear] = num;
|
||||
this.#queSize++;
|
||||
}
|
||||
|
||||
/* 出队 */
|
||||
poll() {
|
||||
const num = this.peek();
|
||||
// 队首指针向后移动一位,若越过尾部则返回到数组头部
|
||||
this.#front = (this.#front + 1) % this.capacity;
|
||||
this.#queSize--;
|
||||
return num;
|
||||
}
|
||||
|
||||
/* 访问队首元素 */
|
||||
peek() {
|
||||
if (this.empty())
|
||||
throw new Error("队列为空");
|
||||
return this.#nums[this.#front];
|
||||
}
|
||||
}
|
||||
[class]{ArrayQueue}-[func]{}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="array_queue.ts"
|
||||
/* 基于环形数组实现的队列 */
|
||||
class ArrayQueue {
|
||||
private nums: number[]; // 用于存储队列元素的数组
|
||||
private front: number; // 队首指针,指向队首元素
|
||||
private queSize: number; // 队列长度
|
||||
|
||||
constructor(capacity: number) {
|
||||
this.nums = new Array(capacity);
|
||||
this.front = this.queSize = 0;
|
||||
}
|
||||
|
||||
/* 获取队列的容量 */
|
||||
get capacity(): number {
|
||||
return this.nums.length;
|
||||
}
|
||||
|
||||
/* 获取队列的长度 */
|
||||
get size(): number {
|
||||
return this.queSize;
|
||||
}
|
||||
|
||||
/* 判断队列是否为空 */
|
||||
empty(): boolean {
|
||||
return this.queSize == 0;
|
||||
}
|
||||
|
||||
/* 入队 */
|
||||
push(num: number): void {
|
||||
if (this.size == this.capacity) {
|
||||
console.log("队列已满");
|
||||
return;
|
||||
}
|
||||
// 计算尾指针,指向队尾索引 + 1
|
||||
// 通过取余操作,实现 rear 越过数组尾部后回到头部
|
||||
const rear = (this.front + this.queSize) % this.capacity;
|
||||
// 尾结点后添加 num
|
||||
this.nums[rear] = num;
|
||||
this.queSize++;
|
||||
}
|
||||
|
||||
/* 出队 */
|
||||
poll(): number {
|
||||
const num = this.peek();
|
||||
// 队首指针向后移动一位,若越过尾部则返回到数组头部
|
||||
this.front = (this.front + 1) % this.capacity;
|
||||
this.queSize--;
|
||||
return num;
|
||||
}
|
||||
|
||||
/* 访问队首元素 */
|
||||
peek(): number {
|
||||
if (this.empty())
|
||||
throw new Error("队列为空");
|
||||
return this.nums[this.front];
|
||||
}
|
||||
}
|
||||
[class]{ArrayQueue}-[func]{}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
|
|
@ -356,125 +356,13 @@ comments: true
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="linkedlist_stack.js"
|
||||
/* 基于链表实现的栈 */
|
||||
class LinkedListStack {
|
||||
#stackPeek; // 将头结点作为栈顶
|
||||
#stkSize = 0; // 栈的长度
|
||||
|
||||
constructor() {
|
||||
this.#stackPeek = null;
|
||||
}
|
||||
|
||||
/* 获取栈的长度 */
|
||||
get size() {
|
||||
return this.#stkSize;
|
||||
}
|
||||
|
||||
/* 判断栈是否为空 */
|
||||
isEmpty() {
|
||||
return this.size == 0;
|
||||
}
|
||||
|
||||
/* 入栈 */
|
||||
push(num) {
|
||||
const node = new ListNode(num);
|
||||
node.next = this.#stackPeek;
|
||||
this.#stackPeek = node;
|
||||
this.#stkSize++;
|
||||
}
|
||||
|
||||
/* 出栈 */
|
||||
pop() {
|
||||
const num = this.peek();
|
||||
if (!this.#stackPeek) {
|
||||
throw new Error("栈为空!");
|
||||
}
|
||||
this.#stackPeek = this.#stackPeek.next;
|
||||
this.#stkSize--;
|
||||
return num;
|
||||
}
|
||||
|
||||
/* 访问栈顶元素 */
|
||||
peek() {
|
||||
if (!this.#stackPeek) {
|
||||
throw new Error("栈为空!");
|
||||
}
|
||||
return this.#stackPeek.val;
|
||||
}
|
||||
|
||||
/* 将链表转化为 Array 并返回 */
|
||||
toArray() {
|
||||
let node = this.#stackPeek;
|
||||
const res = new Array(this.size);
|
||||
for (let i = res.length - 1; i >= 0; i--) {
|
||||
res[i] = node.val;
|
||||
node = node.next;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
[class]{LinkedListStack}-[func]{}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="linkedlist_stack.ts"
|
||||
/* 基于链表实现的栈 */
|
||||
class LinkedListStack {
|
||||
private stackPeek: ListNode | null; // 将头结点作为栈顶
|
||||
private stkSize: number = 0; // 栈的长度
|
||||
|
||||
constructor() {
|
||||
this.stackPeek = null;
|
||||
}
|
||||
|
||||
/* 获取栈的长度 */
|
||||
get size(): number {
|
||||
return this.stkSize;
|
||||
}
|
||||
|
||||
/* 判断栈是否为空 */
|
||||
isEmpty(): boolean {
|
||||
return this.size == 0;
|
||||
}
|
||||
|
||||
/* 入栈 */
|
||||
push(num: number): void {
|
||||
const node = new ListNode(num);
|
||||
node.next = this.stackPeek;
|
||||
this.stackPeek = node;
|
||||
this.stkSize++;
|
||||
}
|
||||
|
||||
/* 出栈 */
|
||||
pop(): number {
|
||||
const num = this.peek();
|
||||
if (!this.stackPeek) {
|
||||
throw new Error("栈为空!");
|
||||
}
|
||||
this.stackPeek = this.stackPeek.next;
|
||||
this.stkSize--;
|
||||
return num;
|
||||
}
|
||||
|
||||
/* 访问栈顶元素 */
|
||||
peek(): number {
|
||||
if (!this.stackPeek) {
|
||||
throw new Error("栈为空!");
|
||||
}
|
||||
return this.stackPeek.val;
|
||||
}
|
||||
|
||||
/* 将链表转化为 Array 并返回 */
|
||||
toArray(): number[] {
|
||||
let node = this.stackPeek;
|
||||
const res = new Array<number>(this.size);
|
||||
for (let i = res.length - 1; i >= 0; i--) {
|
||||
res[i] = node!.val;
|
||||
node = node!.next;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
[class]{LinkedListStack}-[func]{}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
@ -672,73 +560,13 @@ comments: true
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="array_stack.js"
|
||||
/* 基于数组实现的栈 */
|
||||
class ArrayStack {
|
||||
stack;
|
||||
constructor() {
|
||||
this.stack = [];
|
||||
}
|
||||
/* 获取栈的长度 */
|
||||
get size() {
|
||||
return this.stack.length;
|
||||
}
|
||||
/* 判断栈是否为空 */
|
||||
empty() {
|
||||
return this.stack.length === 0;
|
||||
}
|
||||
/* 入栈 */
|
||||
push(num) {
|
||||
this.stack.push(num);
|
||||
}
|
||||
/* 出栈 */
|
||||
pop() {
|
||||
if (this.empty())
|
||||
throw new Error("栈为空");
|
||||
return this.stack.pop();
|
||||
}
|
||||
/* 访问栈顶元素 */
|
||||
top() {
|
||||
if (this.empty())
|
||||
throw new Error("栈为空");
|
||||
return this.stack[this.stack.length - 1];
|
||||
}
|
||||
};
|
||||
[class]{ArrayStack}-[func]{}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="array_stack.ts"
|
||||
/* 基于数组实现的栈 */
|
||||
class ArrayStack {
|
||||
private stack: number[];
|
||||
constructor() {
|
||||
this.stack = [];
|
||||
}
|
||||
/* 获取栈的长度 */
|
||||
get size(): number {
|
||||
return this.stack.length;
|
||||
}
|
||||
/* 判断栈是否为空 */
|
||||
empty(): boolean {
|
||||
return this.stack.length === 0;
|
||||
}
|
||||
/* 入栈 */
|
||||
push(num: number): void {
|
||||
this.stack.push(num);
|
||||
}
|
||||
/* 出栈 */
|
||||
pop(): number | undefined {
|
||||
if (this.empty())
|
||||
throw new Error('栈为空');
|
||||
return this.stack.pop();
|
||||
}
|
||||
/* 访问栈顶元素 */
|
||||
top(): number | undefined {
|
||||
if (this.empty())
|
||||
throw new Error('栈为空');
|
||||
return this.stack[this.stack.length - 1];
|
||||
}
|
||||
};
|
||||
[class]{ArrayStack}-[func]{}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
|
|
@ -329,25 +329,13 @@ G. M. Adelson-Velsky 和 E. M. Landis 在其 1962 年发表的论文 "An algorit
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="avl_tree.js"
|
||||
/* 获取平衡因子 */
|
||||
balanceFactor(node) {
|
||||
// 空结点平衡因子为 0
|
||||
if (node === null) return 0;
|
||||
// 结点平衡因子 = 左子树高度 - 右子树高度
|
||||
return this.height(node.left) - this.height(node.right);
|
||||
}
|
||||
[class]{AVLTree}-[func]{balanceFactor}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="avl_tree.ts"
|
||||
/* 获取平衡因子 */
|
||||
balanceFactor(node: TreeNode): number {
|
||||
// 空结点平衡因子为 0
|
||||
if (node === null) return 0;
|
||||
// 结点平衡因子 = 左子树高度 - 右子树高度
|
||||
return this.height(node.left) - this.height(node.right);
|
||||
}
|
||||
[class]{AVLTree}-[func]{balanceFactor}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
@ -460,37 +448,13 @@ AVL 树的独特之处在于「旋转 Rotation」的操作,其可 **在不影
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="avl_tree.js"
|
||||
/* 右旋操作 */
|
||||
rightRotate(node) {
|
||||
const child = node.left;
|
||||
const grandChild = child.right;
|
||||
// 以 child 为原点,将 node 向右旋转
|
||||
child.right = node;
|
||||
node.left = grandChild;
|
||||
// 更新结点高度
|
||||
this.updateHeight(node);
|
||||
this.updateHeight(child);
|
||||
// 返回旋转后子树的根结点
|
||||
return child;
|
||||
}
|
||||
[class]{AVLTree}-[func]{rightRotate}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="avl_tree.ts"
|
||||
/* 右旋操作 */
|
||||
rightRotate(node: TreeNode): TreeNode {
|
||||
const child = node.left;
|
||||
const grandChild = child.right;
|
||||
// 以 child 为原点,将 node 向右旋转
|
||||
child.right = node;
|
||||
node.left = grandChild;
|
||||
// 更新结点高度
|
||||
this.updateHeight(node);
|
||||
this.updateHeight(child);
|
||||
// 返回旋转后子树的根结点
|
||||
return child;
|
||||
}
|
||||
[class]{AVLTree}-[func]{rightRotate}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
@ -593,37 +557,13 @@ AVL 树的独特之处在于「旋转 Rotation」的操作,其可 **在不影
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="avl_tree.js"
|
||||
/* 左旋操作 */
|
||||
leftRotate(node) {
|
||||
const child = node.right;
|
||||
const grandChild = child.left;
|
||||
// 以 child 为原点,将 node 向左旋转
|
||||
child.left = node;
|
||||
node.right = grandChild;
|
||||
// 更新结点高度
|
||||
this.updateHeight(node);
|
||||
this.updateHeight(child);
|
||||
// 返回旋转后子树的根结点
|
||||
return child;
|
||||
}
|
||||
[class]{AVLTree}-[func]{leftRotate}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="avl_tree.ts"
|
||||
/* 左旋操作 */
|
||||
leftRotate(node: TreeNode): TreeNode {
|
||||
const child = node.right;
|
||||
const grandChild = child.left;
|
||||
// 以 child 为原点,将 node 向左旋转
|
||||
child.left = node;
|
||||
node.right = grandChild;
|
||||
// 更新结点高度
|
||||
this.updateHeight(node);
|
||||
this.updateHeight(child);
|
||||
// 返回旋转后子树的根结点
|
||||
return child;
|
||||
}
|
||||
[class]{AVLTree}-[func]{leftRotate}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
@ -767,69 +707,13 @@ AVL 树的独特之处在于「旋转 Rotation」的操作,其可 **在不影
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="avl_tree.js"
|
||||
/* 执行旋转操作,使该子树重新恢复平衡 */
|
||||
rotate(node) {
|
||||
// 获取结点 node 的平衡因子
|
||||
const balanceFactor = this.balanceFactor(node);
|
||||
// 左偏树
|
||||
if (balanceFactor > 1) {
|
||||
if (this.balanceFactor(node.left) >= 0) {
|
||||
// 右旋
|
||||
return this.rightRotate(node);
|
||||
} else {
|
||||
// 先左旋后右旋
|
||||
node.left = this.leftRotate(node.left);
|
||||
return this.rightRotate(node);
|
||||
}
|
||||
}
|
||||
// 右偏树
|
||||
if (balanceFactor < -1) {
|
||||
if (this.balanceFactor(node.right) <= 0) {
|
||||
// 左旋
|
||||
return this.leftRotate(node);
|
||||
} else {
|
||||
// 先右旋后左旋
|
||||
node.right = this.rightRotate(node.right);
|
||||
return this.leftRotate(node);
|
||||
}
|
||||
}
|
||||
// 平衡树,无需旋转,直接返回
|
||||
return node;
|
||||
}
|
||||
[class]{AVLTree}-[func]{rotate}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="avl_tree.ts"
|
||||
/* 执行旋转操作,使该子树重新恢复平衡 */
|
||||
rotate(node: TreeNode): TreeNode {
|
||||
// 获取结点 node 的平衡因子
|
||||
const balanceFactor = this.balanceFactor(node);
|
||||
// 左偏树
|
||||
if (balanceFactor > 1) {
|
||||
if (this.balanceFactor(node.left) >= 0) {
|
||||
// 右旋
|
||||
return this.rightRotate(node);
|
||||
} else {
|
||||
// 先左旋后右旋
|
||||
node.left = this.leftRotate(node.left);
|
||||
return this.rightRotate(node);
|
||||
}
|
||||
}
|
||||
// 右偏树
|
||||
if (balanceFactor < -1) {
|
||||
if (this.balanceFactor(node.right) <= 0) {
|
||||
// 左旋
|
||||
return this.leftRotate(node);
|
||||
} else {
|
||||
// 先右旋后左旋
|
||||
node.right = this.rightRotate(node.right);
|
||||
return this.leftRotate(node);
|
||||
}
|
||||
}
|
||||
// 平衡树,无需旋转,直接返回
|
||||
return node;
|
||||
}
|
||||
[class]{AVLTree}-[func]{rotate}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
|
|
@ -80,42 +80,13 @@ comments: true
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="binary_search_tree.js"
|
||||
/* 查找结点 */
|
||||
function search(num) {
|
||||
let cur = root;
|
||||
// 循环查找,越过叶结点后跳出
|
||||
while (cur !== null) {
|
||||
// 目标结点在 cur 的右子树中
|
||||
if (cur.val < num) cur = cur.right;
|
||||
// 目标结点在 cur 的左子树中
|
||||
else if (cur.val > num) cur = cur.left;
|
||||
// 找到目标结点,跳出循环
|
||||
else break;
|
||||
}
|
||||
// 返回目标结点
|
||||
return cur;
|
||||
}
|
||||
[class]{}-[func]{search}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="binary_search_tree.ts"
|
||||
/* 查找结点 */
|
||||
function search(num: number): TreeNode | null {
|
||||
let cur = root;
|
||||
// 循环查找,越过叶结点后跳出
|
||||
while (cur !== null) {
|
||||
if (cur.val < num) {
|
||||
cur = cur.right; // 目标结点在 cur 的右子树中
|
||||
} else if (cur.val > num) {
|
||||
cur = cur.left; // 目标结点在 cur 的左子树中
|
||||
} else {
|
||||
break; // 找到目标结点,跳出循环
|
||||
}
|
||||
}
|
||||
// 返回目标结点
|
||||
return cur;
|
||||
}
|
||||
[class]{}-[func]{search}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
@ -245,61 +216,13 @@ comments: true
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="binary_search_tree.js"
|
||||
/* 插入结点 */
|
||||
function insert(num) {
|
||||
// 若树为空,直接提前返回
|
||||
if (root === null) return null;
|
||||
let cur = root, pre = null;
|
||||
// 循环查找,越过叶结点后跳出
|
||||
while (cur !== null) {
|
||||
// 找到重复结点,直接返回
|
||||
if (cur.val === num) return null;
|
||||
pre = cur;
|
||||
// 插入位置在 cur 的右子树中
|
||||
if (cur.val < num) cur = cur.right;
|
||||
// 插入位置在 cur 的左子树中
|
||||
else cur = cur.left;
|
||||
}
|
||||
// 插入结点 val
|
||||
let node = new Tree.TreeNode(num);
|
||||
if (pre.val < num) pre.right = node;
|
||||
else pre.left = node;
|
||||
return node;
|
||||
}
|
||||
[class]{}-[func]{insert}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="binary_search_tree.ts"
|
||||
/* 插入结点 */
|
||||
function insert(num: number): TreeNode | null {
|
||||
// 若树为空,直接提前返回
|
||||
if (root === null) {
|
||||
return null;
|
||||
}
|
||||
let cur = root,
|
||||
pre: TreeNode | null = null;
|
||||
// 循环查找,越过叶结点后跳出
|
||||
while (cur !== null) {
|
||||
if (cur.val === num) {
|
||||
return null; // 找到重复结点,直接返回
|
||||
}
|
||||
pre = cur;
|
||||
if (cur.val < num) {
|
||||
cur = cur.right as TreeNode; // 插入位置在 cur 的右子树中
|
||||
} else {
|
||||
cur = cur.left as TreeNode; // 插入位置在 cur 的左子树中
|
||||
}
|
||||
}
|
||||
// 插入结点 val
|
||||
let node = new TreeNode(num);
|
||||
if (pre!.val < num) {
|
||||
pre!.right = node;
|
||||
} else {
|
||||
pre!.left = node;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
[class]{}-[func]{insert}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
@ -518,118 +441,17 @@ comments: true
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="binary_search_tree.js"
|
||||
/* 删除结点 */
|
||||
function remove(num) {
|
||||
// 若树为空,直接提前返回
|
||||
if (root === null) return null;
|
||||
let cur = root, pre = null;
|
||||
// 循环查找,越过叶结点后跳出
|
||||
while (cur !== null) {
|
||||
// 找到待删除结点,跳出循环
|
||||
if (cur.val === num) break;
|
||||
pre = cur;
|
||||
// 待删除结点在 cur 的右子树中
|
||||
if (cur.val < num) cur = cur.right;
|
||||
// 待删除结点在 cur 的左子树中
|
||||
else cur = cur.left;
|
||||
}
|
||||
// 若无待删除结点,则直接返回
|
||||
if (cur === null) return null;
|
||||
// 子结点数量 = 0 or 1
|
||||
if (cur.left === null || cur.right === null) {
|
||||
// 当子结点数量 = 0 / 1 时, child = null / 该子结点
|
||||
let child = cur.left !== null ? cur.left : cur.right;
|
||||
// 删除结点 cur
|
||||
if (pre.left === cur) pre.left = child;
|
||||
else pre.right = child;
|
||||
}
|
||||
// 子结点数量 = 2
|
||||
else {
|
||||
// 获取中序遍历中 cur 的下一个结点
|
||||
let nex = getInOrderNext(cur.right);
|
||||
let tmp = nex.val;
|
||||
// 递归删除结点 nex
|
||||
remove(nex.val);
|
||||
// 将 nex 的值复制给 cur
|
||||
cur.val = tmp;
|
||||
}
|
||||
return cur;
|
||||
}
|
||||
[class]{}-[func]{remove}
|
||||
|
||||
/* 获取中序遍历中的下一个结点(仅适用于 root 有左子结点的情况) */
|
||||
function getInOrderNext(root) {
|
||||
if (root === null) return root;
|
||||
// 循环访问左子结点,直到叶结点时为最小结点,跳出
|
||||
while (root.left !== null) {
|
||||
root = root.left;
|
||||
}
|
||||
return root;
|
||||
}
|
||||
[class]{}-[func]{getInOrderNext}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="binary_search_tree.ts"
|
||||
/* 删除结点 */
|
||||
function remove(num: number): TreeNode | null {
|
||||
// 若树为空,直接提前返回
|
||||
if (root === null) {
|
||||
return null;
|
||||
}
|
||||
let cur = root,
|
||||
pre: TreeNode | null = null;
|
||||
// 循环查找,越过叶结点后跳出
|
||||
while (cur !== null) {
|
||||
// 找到待删除结点,跳出循环
|
||||
if (cur.val === num) {
|
||||
break;
|
||||
}
|
||||
pre = cur;
|
||||
if (cur.val < num) {
|
||||
cur = cur.right as TreeNode; // 待删除结点在 cur 的右子树中
|
||||
} else {
|
||||
cur = cur.left as TreeNode; // 待删除结点在 cur 的左子树中
|
||||
}
|
||||
}
|
||||
// 若无待删除结点,则直接返回
|
||||
if (cur === null) {
|
||||
return null;
|
||||
}
|
||||
// 子结点数量 = 0 or 1
|
||||
if (cur.left === null || cur.right === null) {
|
||||
// 当子结点数量 = 0 / 1 时, child = null / 该子结点
|
||||
let child = cur.left !== null ? cur.left : cur.right;
|
||||
// 删除结点 cur
|
||||
if (pre!.left === cur) {
|
||||
pre!.left = child;
|
||||
} else {
|
||||
pre!.right = child;
|
||||
}
|
||||
}
|
||||
// 子结点数量 = 2
|
||||
else {
|
||||
// 获取中序遍历中 cur 的下一个结点
|
||||
let next = getInOrderNext(cur.right);
|
||||
let tmp = next!.val;
|
||||
// 递归删除结点 nex
|
||||
remove(next!.val);
|
||||
// 将 nex 的值复制给 cur
|
||||
cur.val = tmp;
|
||||
}
|
||||
return cur;
|
||||
}
|
||||
[class]{}-[func]{remove}
|
||||
|
||||
/* 获取中序遍历中的下一个结点(仅适用于 root 有左子结点的情况) */
|
||||
function getInOrderNext(root: TreeNode | null): TreeNode | null {
|
||||
if (root === null) {
|
||||
return null;
|
||||
}
|
||||
// 循环访问左子结点,直到叶结点时为最小结点,跳出
|
||||
while (root.left !== null) {
|
||||
root = root.left;
|
||||
}
|
||||
return root;
|
||||
}
|
||||
[class]{}-[func]{getInOrderNext}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
|
|
@ -67,45 +67,13 @@ comments: true
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="binary_tree_bfs.js"
|
||||
/* 层序遍历 */
|
||||
function hierOrder(root) {
|
||||
// 初始化队列,加入根结点
|
||||
let queue = [root];
|
||||
// 初始化一个列表,用于保存遍历序列
|
||||
let list = [];
|
||||
while (queue.length) {
|
||||
let node = queue.shift(); // 队列出队
|
||||
list.push(node.val); // 保存结点值
|
||||
if (node.left)
|
||||
queue.push(node.left); // 左子结点入队
|
||||
if (node.right)
|
||||
queue.push(node.right); // 右子结点入队
|
||||
}
|
||||
return list;
|
||||
}
|
||||
[class]{}-[func]{hierOrder}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="binary_tree_bfs.ts"
|
||||
/* 层序遍历 */
|
||||
function hierOrder(root: TreeNode | null): number[] {
|
||||
// 初始化队列,加入根结点
|
||||
const queue = [root];
|
||||
// 初始化一个列表,用于保存遍历序列
|
||||
const list: number[] = [];
|
||||
while (queue.length) {
|
||||
let node = queue.shift() as TreeNode; // 队列出队
|
||||
list.push(node.val); // 保存结点值
|
||||
if (node.left) {
|
||||
queue.push(node.left); // 左子结点入队
|
||||
}
|
||||
if (node.right) {
|
||||
queue.push(node.right); // 右子结点入队
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
[class]{}-[func]{hierOrder}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
@ -258,69 +226,21 @@ comments: true
|
|||
=== "JavaScript"
|
||||
|
||||
```javascript title="binary_tree_dfs.js"
|
||||
/* 前序遍历 */
|
||||
function preOrder(root){
|
||||
if (root === null) return;
|
||||
// 访问优先级:根结点 -> 左子树 -> 右子树
|
||||
list.push(root.val);
|
||||
preOrder(root.left);
|
||||
preOrder(root.right);
|
||||
}
|
||||
|
||||
/* 中序遍历 */
|
||||
function inOrder(root) {
|
||||
if (root === null) return;
|
||||
// 访问优先级:左子树 -> 根结点 -> 右子树
|
||||
inOrder(root.left);
|
||||
list.push(root.val);
|
||||
inOrder(root.right);
|
||||
}
|
||||
|
||||
/* 后序遍历 */
|
||||
function postOrder(root) {
|
||||
if (root === null) return;
|
||||
// 访问优先级:左子树 -> 右子树 -> 根结点
|
||||
postOrder(root.left);
|
||||
postOrder(root.right);
|
||||
list.push(root.val);
|
||||
}
|
||||
[class]{}-[func]{preOrder}
|
||||
|
||||
[class]{}-[func]{inOrder}
|
||||
|
||||
[class]{}-[func]{postOrder}
|
||||
```
|
||||
|
||||
=== "TypeScript"
|
||||
|
||||
```typescript title="binary_tree_dfs.ts"
|
||||
/* 前序遍历 */
|
||||
function preOrder(root: TreeNode | null): void {
|
||||
if (root === null) {
|
||||
return;
|
||||
}
|
||||
// 访问优先级:根结点 -> 左子树 -> 右子树
|
||||
list.push(root.val);
|
||||
preOrder(root.left);
|
||||
preOrder(root.right);
|
||||
}
|
||||
|
||||
/* 中序遍历 */
|
||||
function inOrder(root: TreeNode | null): void {
|
||||
if (root === null) {
|
||||
return;
|
||||
}
|
||||
// 访问优先级:左子树 -> 根结点 -> 右子树
|
||||
inOrder(root.left);
|
||||
list.push(root.val);
|
||||
inOrder(root.right);
|
||||
}
|
||||
|
||||
/* 后序遍历 */
|
||||
function postOrder(root: TreeNode | null): void {
|
||||
if (root === null) {
|
||||
return;
|
||||
}
|
||||
// 访问优先级:左子树 -> 右子树 -> 根结点
|
||||
postOrder(root.left);
|
||||
postOrder(root.right);
|
||||
list.push(root.val);
|
||||
}
|
||||
[class]{}-[func]{preOrder}
|
||||
|
||||
[class]{}-[func]{inOrder}
|
||||
|
||||
[class]{}-[func]{postOrder}
|
||||
```
|
||||
|
||||
=== "C"
|
||||
|
|
|
@ -1,8 +1,14 @@
|
|||
# This script is borrowed from https://gist.github.com/cobyism/4730490
|
||||
|
||||
git add build && git commit -m "build"
|
||||
git subtree push --prefix build origin built-docs
|
||||
cd build
|
||||
git add .
|
||||
git commit -m "build"
|
||||
git push -u origin docs
|
||||
cd ..
|
||||
|
||||
mkdocs build --clean
|
||||
git add site && git commit -m "deploy"
|
||||
git subtree push --prefix site origin gh-pages
|
||||
|
||||
cd site
|
||||
git add .
|
||||
git commit -m "deploy"
|
||||
git push -u origin gh-pages
|
||||
|
|
|
@ -16,10 +16,10 @@ class ExtractCodeBlocksJSTS(ExtractCodeBlocksJava):
|
|||
super().__init__()
|
||||
|
||||
# Pattern to match function names and class names
|
||||
self.func_pattern = r'\s*(function|private|public|)\s*(\S*)\(.*\)(:|)\s*(\S*)\s*{\s*\n'
|
||||
self.func_pattern = r'(\s*)(function|private|public|)\s*(\S*)\(.*\)(:|)\s*(.*)\s+{\s*\n'
|
||||
self.class_pattern = r'class\s+(\w+)\s*\{'
|
||||
|
||||
self.func_pattern_keys = ["total", "prefix", "label", ":", "return"]
|
||||
self.func_pattern_keys = ["total", "ind", "prefix", "label", ":", "return"]
|
||||
self.class_pattern_keys = ["total", "label"]
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue