This commit is contained in:
krahets 2023-02-08 22:16:25 +08:00
parent 30ed83e5b1
commit af3542e3c0
17 changed files with 258 additions and 100 deletions

View file

@ -202,9 +202,9 @@ elementAddr = firtstElementAddr + elementLength * elementIndex
```csharp title="array.cs"
/* 随机返回一个数组元素 */
int RandomAccess(int[] nums)
int randomAccess(int[] nums)
{
Random random=new();
Random random = new();
// 在区间 [0, nums.Length) 中随机抽取一个数字
int randomIndex = random.Next(nums.Length);
// 获取并返回随机元素
@ -355,7 +355,7 @@ elementAddr = firtstElementAddr + elementLength * elementIndex
```csharp title="array.cs"
/* 扩展数组长度 */
int[] Extend(int[] nums, int enlarge)
int[] extend(int[] nums, int enlarge)
{
// 初始化一个扩展长度后的数组
int[] res = new int[nums.Length + enlarge];
@ -548,7 +548,7 @@ elementAddr = firtstElementAddr + elementLength * elementIndex
```csharp title="array.cs"
/* 在数组的索引 index 处插入元素 num */
void Insert(int[] nums, int num, int index)
void insert(int[] nums, int num, int index)
{
// 把索引 index 以及之后的所有元素向后移动一位
for (int i = nums.Length - 1; i > index; i--)
@ -558,8 +558,9 @@ elementAddr = firtstElementAddr + elementLength * elementIndex
// 将 num 赋给 index 处元素
nums[index] = num;
}
/* 删除索引 index 处元素 */
void Remove(int[] nums, int index)
void remove(int[] nums, int index)
{
// 把索引 index 之后的所有元素向前移动一位
for (int i = index; i < nums.Length - 1; i++)
@ -725,7 +726,7 @@ elementAddr = firtstElementAddr + elementLength * elementIndex
```csharp title="array.cs"
/* 遍历数组 */
void Traverse(int[] nums)
void traverse(int[] nums)
{
int count = 0;
// 通过索引遍历数组
@ -868,7 +869,7 @@ elementAddr = firtstElementAddr + elementLength * elementIndex
```csharp title="array.cs"
/* 在数组中查找指定元素 */
int Find(int[] nums, int target)
int find(int[] nums, int target)
{
for (int i = 0; i < nums.Length; i++)
{

View file

@ -459,22 +459,22 @@ comments: true
=== "C#"
```csharp title="linked_list.cs"
// 在链表的结点 n0 之后插入结点 P
void Insert(ListNode n0, ListNode P)
/* 在链表的结点 n0 之后插入结点 P */
void insert(ListNode n0, ListNode P)
{
ListNode n1 = n0.next;
ListNode? n1 = n0.next;
n0.next = P;
P.next = n1;
}
// 删除链表的结点 n0 之后的首个结点
void Remove(ListNode n0)
/* 删除链表的结点 n0 之后的首个结点 */
void remove(ListNode n0)
{
if (n0.next == null)
return;
// n0 -> P -> n1
ListNode P = n0.next;
ListNode n1 = P.next;
ListNode? n1 = P.next;
n0.next = n1;
}
```
@ -620,8 +620,8 @@ comments: true
=== "C#"
```csharp title="linked_list.cs"
// 访问链表中索引为 index 的结点
ListNode Access(ListNode head, int index)
/* 访问链表中索引为 index 的结点 */
ListNode? access(ListNode head, int index)
{
for (int i = 0; i < index; i++)
{
@ -776,8 +776,8 @@ comments: true
=== "C#"
```csharp title="linked_list.cs"
// 在链表中查找值为 target 的首个结点
int Find(ListNode head, int target)
/* 在链表中查找值为 target 的首个结点 */
int find(ListNode head, int target)
{
int index = 0;
while (head != null)

View file

@ -1323,101 +1323,114 @@ comments: true
=== "C#"
```csharp title="my_list.cs"
/* 列表类简易实现 */
class MyList
{
private int[] nums; // 数组(存储列表元素)
private int capacity = 10; // 列表容量
private int size = 0; // 列表长度(即当前元素数量)
private int numsCapacity = 10; // 列表容量
private int numsSize = 0; // 列表长度(即当前元素数量)
private int extendRatio = 2; // 每次列表扩容的倍数
/* 构造函数 */
public MyList()
{
nums = new int[capacity];
nums = new int[numsCapacity];
}
/* 获取列表长度(即当前元素数量)*/
public int Size()
public int size()
{
return size;
return numsSize;
}
/* 获取列表容量 */
public int Capacity()
public int capacity()
{
return capacity;
return numsCapacity;
}
/* 访问元素 */
public int Get(int index)
public int get(int index)
{
// 索引如果越界则抛出异常,下同
if (index < 0 || index >= size)
if (index < 0 || index >= numsSize)
throw new IndexOutOfRangeException("索引越界");
return nums[index];
}
/* 更新元素 */
public void Set(int index, int num)
public void set(int index, int num)
{
if (index < 0 || index >= size)
if (index < 0 || index >= numsSize)
throw new IndexOutOfRangeException("索引越界");
nums[index] = num;
}
/* 尾部添加元素 */
public void Add(int num)
public void add(int num)
{
// 元素数量超出容量时,触发扩容机制
if (size == Capacity())
ExtendCapacity();
nums[size] = num;
if (numsSize == numsCapacity)
extendCapacity();
nums[numsSize] = num;
// 更新元素数量
size++;
numsSize++;
}
/* 中间插入元素 */
public void Insert(int index, int num)
public void insert(int index, int num)
{
if (index < 0 || index >= size)
if (index < 0 || index >= numsSize)
throw new IndexOutOfRangeException("索引越界");
// 元素数量超出容量时,触发扩容机制
if (size == Capacity())
ExtendCapacity();
if (numsSize == numsCapacity)
extendCapacity();
// 将索引 index 以及之后的元素都向后移动一位
for (int j = size - 1; j >= index; j--)
for (int j = numsSize - 1; j >= index; j--)
{
nums[j + 1] = nums[j];
}
nums[index] = num;
// 更新元素数量
size++;
numsSize++;
}
/* 删除元素 */
public int Remove(int index)
public int remove(int index)
{
if (index < 0 || index >= size)
if (index < 0 || index >= numsSize)
throw new IndexOutOfRangeException("索引越界");
int num = nums[index];
// 将索引 index 之后的元素都向前移动一位
for (int j = index; j < size - 1; j++)
for (int j = index; j < numsSize - 1; j++)
{
nums[j] = nums[j + 1];
}
// 更新元素数量
size--;
numsSize--;
// 返回被删除元素
return num;
}
/* 列表扩容 */
public void ExtendCapacity()
public void extendCapacity()
{
// 新建一个长度为 size 的数组,并将原数组拷贝到新数组
System.Array.Resize(ref nums, Capacity() * extendRatio);
// 新建一个长度为 numsCapacity * extendRatio 的数组,并将原数组拷贝到新数组
System.Array.Resize(ref nums, numsCapacity * extendRatio);
// 更新列表容量
capacity = nums.Length;
numsCapacity = nums.Length;
}
/* 将列表转换为数组 */
public int[] toArray()
{
// 仅转换有效长度范围内的列表元素
int[] nums = new int[numsSize];
for (int i = 0; i < numsSize; i++)
{
nums[i] = get(i);
}
return nums;
}
}
```

View file

@ -1332,8 +1332,8 @@ $$
int quadraticRecur(int n)
{
if (n <= 0) return 0;
// 数组 nums 长度为 n, n-1, ..., 2, 1
int[] nums = new int[n];
Console.WriteLine("递归 n = " + n + " 中的 nums 长度 = " + nums.Length);
return quadraticRecur(n - 1);
}
```

View file

@ -139,22 +139,20 @@ comments: true
=== "C#"
```csharp title="leetcode_two_sum.cs"
class SolutionBruteForce
/* 方法一:暴力枚举 */
int[] twoSumBruteForce(int[] nums, int target)
{
public int[] twoSum(int[] nums, int target)
int size = nums.Length;
// 两层循环,时间复杂度 O(n^2)
for (int i = 0; i < size - 1; i++)
{
int size = nums.Length;
// 两层循环,时间复杂度 O(n^2)
for (int i = 0; i < size - 1; i++)
for (int j = i + 1; j < size; j++)
{
for (int j = i + 1; j < size; j++)
{
if (nums[i] + nums[j] == target)
return new int[] { i, j };
}
if (nums[i] + nums[j] == target)
return new int[] { i, j };
}
return new int[0];
}
return new int[0];
}
```
@ -321,24 +319,22 @@ comments: true
=== "C#"
```csharp title="leetcode_two_sum.cs"
class SolutionHashMap
/* 方法二:辅助哈希表 */
int[] twoSumHashTable(int[] nums, int target)
{
public int[] twoSum(int[] nums, int target)
int size = nums.Length;
// 辅助哈希表,空间复杂度 O(n)
Dictionary<int, int> dic = new();
// 单层循环,时间复杂度 O(n)
for (int i = 0; i < size; i++)
{
int size = nums.Length;
// 辅助哈希表,空间复杂度 O(n)
Dictionary<int, int> dic = new();
// 单层循环,时间复杂度 O(n)
for (int i = 0; i < size; i++)
if (dic.ContainsKey(target - nums[i]))
{
if (dic.ContainsKey(target - nums[i]))
{
return new int[] { dic[target - nums[i]], i };
}
dic.Add(nums[i], i);
return new int[] { dic[target - nums[i]], i };
}
return new int[0];
dic.Add(nums[i], i);
}
return new int[0];
}
```

View file

@ -1164,7 +1164,7 @@ $$
{
int count = 0;
// 循环次数与数组长度成正比
foreach(int num in nums)
foreach (int num in nums)
{
count++;
}
@ -1560,7 +1560,6 @@ $$
}
return count;
}
```
=== "Swift"

View file

@ -244,7 +244,7 @@ comments: true
=== "C#"
```csharp title="graph_adjacency_matrix.cs"
[class]{GraphAdjMat}-[func]{}
```
=== "Swift"
@ -568,7 +568,9 @@ comments: true
=== "C#"
```csharp title="graph_adjacency_list.cs"
[class]{Vertex}-[func]{}
[class]{GraphAdjList}-[func]{}
```
=== "Swift"

View file

@ -924,7 +924,7 @@ $$
this.val = val;
}
}
/* 基于数组简易实现的哈希表 */
class ArrayHashMap
{
@ -932,18 +932,20 @@ $$
public ArrayHashMap()
{
// 初始化一个长度为 100 的桶(数组)
bucket = new ();
bucket = new();
for (int i = 0; i < 100; i++)
{
bucket.Add(null);
}
}
/* 哈希函数 */
private int hashFunc(int key)
{
int index = key % 100;
return index;
}
/* 查询操作 */
public String? get(int key)
{
@ -952,19 +954,66 @@ $$
if (pair == null) return null;
return pair.val;
}
/* 添加操作 */
public void put(int key, String val)
{
Entry pair = new Entry(key, val);
int index = hashFunc(key);
bucket[index]=pair;
bucket[index] = pair;
}
/* 删除操作 */
public void remove(int key)
{
int index = hashFunc(key);
// 置为 null ,代表删除
bucket[index]=null;
bucket[index] = null;
}
/* 获取所有键值对 */
public List<Entry> entrySet()
{
List<Entry> entrySet = new();
foreach (Entry? pair in bucket)
{
if (pair != null)
entrySet.Add(pair);
}
return entrySet;
}
/* 获取所有键 */
public List<int> keySet()
{
List<int> keySet = new();
foreach (Entry? pair in bucket)
{
if (pair != null)
keySet.Add(pair.key);
}
return keySet;
}
/* 获取所有值 */
public List<String> valueSet()
{
List<String> valueSet = new();
foreach (Entry? pair in bucket)
{
if (pair != null)
valueSet.Add(pair.val);
}
return valueSet;
}
/* 打印哈希表 */
public void print()
{
foreach (Entry kv in entrySet())
{
Console.WriteLine(kv.key + " -> " + kv.val);
}
}
}
```

View file

@ -380,7 +380,11 @@ comments: true
=== "C#"
```csharp title="my_heap.cs"
[class]{MaxHeap}-[func]{left}
[class]{MaxHeap}-[func]{right}
[class]{MaxHeap}-[func]{parent}
```
=== "Swift"
@ -472,7 +476,7 @@ comments: true
=== "C#"
```csharp title="my_heap.cs"
[class]{MaxHeap}-[func]{peek}
```
=== "Swift"
@ -665,7 +669,9 @@ comments: true
=== "C#"
```csharp title="my_heap.cs"
[class]{MaxHeap}-[func]{push}
[class]{MaxHeap}-[func]{siftUp}
```
=== "Swift"
@ -951,7 +957,9 @@ comments: true
=== "C#"
```csharp title="my_heap.cs"
[class]{MaxHeap}-[func]{poll}
[class]{MaxHeap}-[func]{siftDown}
```
=== "Swift"
@ -1097,7 +1105,7 @@ comments: true
=== "C#"
```csharp title="my_heap.cs"
[class]{MaxHeap}-[func]{MaxHeap}
```
=== "Swift"

View file

@ -129,7 +129,6 @@ comments: true
// 未找到目标元素,返回 -1
return -1;
}
```
=== "Swift"

View file

@ -398,7 +398,6 @@ comments: true
quickSort(nums, left, pivot - 1);
quickSort(nums, pivot + 1, right);
}
```
=== "Swift"
@ -679,7 +678,17 @@ comments: true
// 将中位数交换至数组最左端
swap(nums, left, med);
// 以 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; // 返回基准数的索引
}
```

View file

@ -732,7 +732,9 @@ comments: true
=== "C#"
```csharp title="linkedlist_deque.cs"
[class]{ListNode}-[func]{}
[class]{LinkedListDeque}-[func]{}
```
=== "Swift"

View file

@ -690,21 +690,25 @@ comments: true
{
private ListNode? front, rear; // 头结点 front ,尾结点 rear
private int queSize = 0;
public LinkedListQueue()
{
front = null;
rear = null;
}
/* 获取队列的长度 */
public int size()
{
return queSize;
}
/* 判断队列是否为空 */
public bool isEmpty()
{
return size() == 0;
}
/* 入队 */
public void push(int num)
{
@ -724,6 +728,7 @@ comments: true
}
queSize++;
}
/* 出队 */
public int poll()
{
@ -733,6 +738,7 @@ comments: true
queSize--;
return num;
}
/* 访问队首元素 */
public int peek()
{
@ -740,6 +746,22 @@ comments: true
throw new Exception();
return front.val;
}
/* 将链表转化为 Array 并返回 */
public int[] toArray()
{
if (front == null)
return Array.Empty<int>();
ListNode node = front;
int[] res = new int[size()];
for (int i = 0; i < res.Length; i++)
{
res[i] = node.val;
node = node.next;
}
return res;
}
}
```
@ -975,11 +997,10 @@ comments: true
/* 将数组转化为 Vector 并返回 */
vector<int> toVector() {
int cap = queCapacity;
// 仅转换有效长度范围内的列表元素
vector<int> arr(queSize);
for (int i = 0, j = front; i < queSize; i++, j++) {
arr[i] = nums[j % cap];
arr[i] = nums[j % queCapacity];
}
return arr;
}
@ -1328,6 +1349,18 @@ comments: true
throw new Exception();
return nums[front];
}
/* 返回数组 */
public int[] toArray()
{
// 仅转换有效长度范围内的列表元素
int[] res = new int[queSize];
for (int i = 0, j = front; i < queSize; i++, j++)
{
res[i] = nums[j % this.capacity()];
}
return res;
}
}
```

View file

@ -638,22 +638,26 @@ comments: true
/* 基于链表实现的栈 */
class LinkedListStack
{
private ListNode stackPeek; // 将头结点作为栈顶
private ListNode? stackPeek; // 将头结点作为栈顶
private int stkSize = 0; // 栈的长度
public LinkedListStack()
{
stackPeek = null;
}
/* 获取栈的长度 */
public int size()
{
return stkSize;
}
/* 判断栈是否为空 */
public bool isEmpty()
{
return size() == 0;
}
/* 入栈 */
public void push(int num)
{
@ -662,21 +666,42 @@ comments: true
stackPeek = node;
stkSize++;
}
/* 出栈 */
public int pop()
{
if (stackPeek == null)
throw new Exception();
int num = peek();
stackPeek = stackPeek?.next;
stackPeek = stackPeek.next;
stkSize--;
return num;
}
/* 访问栈顶元素 */
public int peek()
{
if (size() == 0)
if (size() == 0 || stackPeek == null)
throw new Exception();
return stackPeek.val;
}
/* 将 List 转化为 Array 并返回 */
public int[] toArray()
{
if (stackPeek == null)
return Array.Empty<int>();
ListNode node = stackPeek;
int[] res = new int[size()];
for (int i = res.Length - 1; i >= 0; i--)
{
res[i] = node.val;
node = node.next;
}
return res;
}
}
```
@ -1047,21 +1072,25 @@ comments: true
// 初始化列表(动态数组)
stack = new();
}
/* 获取栈的长度 */
public int size()
{
return stack.Count();
}
/* 判断栈是否为空 */
public bool isEmpty()
{
return size() == 0;
}
/* 入栈 */
public void push(int num)
{
stack.Add(num);
}
/* 出栈 */
public int pop()
{
@ -1071,6 +1100,7 @@ comments: true
stack.RemoveAt(size() - 1);
return val;
}
/* 访问栈顶元素 */
public int peek()
{
@ -1078,6 +1108,12 @@ comments: true
throw new Exception();
return stack[size() - 1];
}
/* 将 List 转化为 Array 并返回 */
public int[] toArray()
{
return stack.ToArray();
}
}
```

View file

@ -270,14 +270,14 @@ G. M. Adelson-Velsky 和 E. M. Landis 在其 1962 年发表的论文 "An algorit
```csharp title="avl_tree.cs"
/* 获取结点高度 */
public int height(TreeNode? node)
int height(TreeNode? node)
{
// 空结点高度为 -1 ,叶结点高度为 0
return node == null ? -1 : node.height;
}
/* 更新结点高度 */
private void updateHeight(TreeNode node)
void updateHeight(TreeNode node)
{
// 结点高度等于最高子树高度 + 1
node.height = Math.Max(height(node.left), height(node.right)) + 1;
@ -396,7 +396,7 @@ G. M. Adelson-Velsky 和 E. M. Landis 在其 1962 年发表的论文 "An algorit
```csharp title="avl_tree.cs"
/* 获取平衡因子 */
public int balanceFactor(TreeNode? node)
int balanceFactor(TreeNode? node)
{
// 空结点平衡因子为 0
if (node == null) return 0;
@ -1284,14 +1284,14 @@ AVL 树的独特之处在于「旋转 Rotation」的操作其可 **在不影
```csharp title="avl_tree.cs"
/* 插入结点 */
public TreeNode? insert(int val)
TreeNode? insert(int val)
{
root = insertHelper(root, val);
return root;
}
/* 递归插入结点(辅助函数) */
private TreeNode? insertHelper(TreeNode? node, int val)
TreeNode? insertHelper(TreeNode? node, int val)
{
if (node == null) return new TreeNode(val);
/* 1. 查找插入位置,并插入结点 */
@ -1650,14 +1650,14 @@ AVL 树的独特之处在于「旋转 Rotation」的操作其可 **在不影
```csharp title="avl_tree.cs"
/* 删除结点 */
public TreeNode? remove(int val)
TreeNode? remove(int val)
{
root = removeHelper(root, val);
return root;
}
/* 递归删除结点(辅助函数) */
private TreeNode? removeHelper(TreeNode? node, int val)
TreeNode? removeHelper(TreeNode? node, int val)
{
if (node == null) return null;
/* 1. 查找结点,并删除之 */
@ -1691,6 +1691,18 @@ AVL 树的独特之处在于「旋转 Rotation」的操作其可 **在不影
// 返回子树的根结点
return node;
}
/* 获取中序遍历中的下一个结点(仅适用于 root 有左子结点的情况) */
TreeNode? getInOrderNext(TreeNode? node)
{
if (node == null) return node;
// 循环访问左子结点,直到叶结点时为最小结点,跳出
while (node.left != null)
{
node = node.left;
}
return node;
}
```
=== "Swift"

View file

@ -437,7 +437,7 @@ comments: true
// 插入位置在 cur 的左子树中
else cur = cur.left;
}
// 插入结点 val
TreeNode node = new TreeNode(num);
if (pre != null)
@ -939,7 +939,7 @@ comments: true
}
/* 获取中序遍历中的下一个结点(仅适用于 root 有左子结点的情况) */
private TreeNode? getInOrderNext(TreeNode? root)
TreeNode? getInOrderNext(TreeNode? root)
{
if (root == null) return root;
// 循环访问左子结点,直到叶结点时为最小结点,跳出

View file

@ -165,7 +165,7 @@ comments: true
```csharp title="binary_tree_bfs.cs"
/* 层序遍历 */
public List<int?> hierOrder(TreeNode root)
List<int> hierOrder(TreeNode root)
{
// 初始化队列,加入根结点
Queue<TreeNode> queue = new();
@ -183,7 +183,6 @@ comments: true
}
return list;
}
```
=== "Swift"