資料結構類
-
陣列 (Array)
- 雙指標 (Two Pointers)
- 滑動視窗 (Sliding Window)
- 字首和 (Prefix Sum)
-
連結串列 (Linked List)
- 單連結串列反轉 (Reverse Linked List)
- 連結串列合併 (Merge Linked Lists)
- 連結串列環檢測 (Cycle Detection)
-
棧和佇列 (Stack and Queue)
- 棧的基本操作 (Basic Stack Operations)
- 佇列的基本操作 (Basic Queue Operations)
- 單調棧 (Monotonic Stack)
- 優先佇列 (Priority Queue)
-
樹 (Tree)
- 二叉樹遍歷 (Binary Tree Traversal)
- 二叉搜尋樹 (Binary Search Tree)
- 平衡二叉樹 (Balanced Binary Tree)
- 樹的最大/最小深度 (Max/Min Depth of Tree)
- 樹的路徑問題 (Tree Path Problems)
-
圖 (Graph)
- 圖的遍歷 (Graph Traversal: DFS and BFS)
- 最短路徑 (Shortest Path)
- 拓撲排序 (Topological Sorting)
- 連通分量 (Connected Components)
題目型別類
-
排序與搜尋 (Sorting and Searching)
- 經典排序演算法 (Classic Sorting Algorithms: Quick Sort, Merge Sort, etc.)
- 二分查詢 (Binary Search)
- 快速選擇 (Quick Select)
-
動態規劃 (Dynamic Programming)
- 斐波那契數列 (Fibonacci Sequence)
- 揹包問題 (Knapsack Problem)
- 最長公共子序列 (Longest Common Subsequence)
- 最長遞增子序列 (Longest Increasing Subsequence)
-
回溯法 (Backtracking)
- 排列與組合 (Permutations and Combinations)
- N皇后問題 (N-Queens Problem)
- 子集生成 (Subset Generation)
-
貪心演算法 (Greedy Algorithm)
- 區間排程 (Interval Scheduling)
- 跳躍遊戲 (Jump Game)
- 分糖果問題 (Candy Distribution)
-
字串 (String)
- 字串匹配 (String Matching: KMP, Rabin-Karp, etc.)
- 字串變換 (String Transformation)
- 最長公共子串 (Longest Common Substring)
-
數學與位運算 (Math and Bit Manipulation)
- 素數問題 (Prime Numbers)
- 數學組合 (Mathematical Combinations)
- 位運算技巧 (Bit Manipulation Tricks)
資料結構類
1. 陣列 (Array)
雙指標 (Two Pointers)
模板:刪除排序陣列中的重複項
public int RemoveDuplicates(int[] nums) {
if (nums.Length == 0) return 0;
int i = 0;
for (int j = 1; j < nums.Length; j++) {
if (nums[j] != nums[i]) {
i++;
nums[i] = nums[j];
}
}
return i + 1;
}
滑動視窗 (Sliding Window)
模板:最大連續子陣列和
public int MaxSubArray(int[] nums) {
int maxSum = nums[0];
int currentSum = nums[0];
for (int i = 1; i < nums.Length; i++) {
currentSum = Math.Max(nums[i], currentSum + nums[i]);
maxSum = Math.Max(maxSum, currentSum);
}
return maxSum;
}
字首和 (Prefix Sum)
模板:陣列的字首和
public int[] PrefixSum(int[] nums) {
int[] prefixSum = new int[nums.Length];
prefixSum[0] = nums[0];
for (int i = 1; i < nums.Length; i++) {
prefixSum[i] = prefixSum[i - 1] + nums[i];
}
return prefixSum;
}
2. 連結串列 (Linked List)
單連結串列反轉 (Reverse Linked List)
模板:反轉連結串列
public ListNode ReverseList(ListNode head) {
ListNode prev = null;
ListNode curr = head;
while (curr != null) {
ListNode nextTemp = curr.next;
curr.next = prev;
prev = curr;
curr = nextTemp;
}
return prev;
}
連結串列合併 (Merge Linked Lists)
模板:合併兩個有序連結串列
public ListNode MergeTwoLists(ListNode l1, ListNode l2) {
if (l1 == null) return l2;
if (l2 == null) return l1;
if (l1.val < l2.val) {
l1.next = MergeTwoLists(l1.next, l2);
return l1;
} else {
l2.next = MergeTwoLists(l1, l2.next);
return l2;
}
}
連結串列環檢測 (Cycle Detection)
模板:檢測連結串列環
public bool HasCycle(ListNode head) {
if (head == null || head.next == null) return false;
ListNode slow = head;
ListNode fast = head.next;
while (slow != fast) {
if (fast == null || fast.next == null) return false;
slow = slow.next;
fast = fast.next.next;
}
return true;
}
3. 棧和佇列 (Stack and Queue)
棧的基本操作 (Basic Stack Operations)
模板:棧的基本操作
Stack<int> stack = new Stack<int>();
stack.Push(1);
stack.Push(2);
int top = stack.Peek();
stack.Pop();
bool isEmpty = stack.Count == 0;
佇列的基本操作 (Basic Queue Operations)
模板:佇列的基本操作
Queue<int> queue = new Queue<int>();
queue.Enqueue(1);
queue.Enqueue(2);
int front = queue.Peek();
queue.Dequeue();
bool isEmpty = queue.Count == 0;
單調棧 (Monotonic Stack)
模板:單調棧用於下一個更大元素問題
public int[] NextGreaterElement(int[] nums) {
int[] result = new int[nums.Length];
Stack<int> stack = new Stack<int>();
for (int i = nums.Length - 1; i >= 0; i--) {
while (stack.Count > 0 && stack.Peek() <= nums[i]) {
stack.Pop();
}
result[i] = stack.Count == 0 ? -1 : stack.Peek();
stack.Push(nums[i]);
}
return result;
}
優先佇列 (Priority Queue)
模板:優先佇列的基本操作
PriorityQueue<int, int> pq = new PriorityQueue<int, int>();
pq.Enqueue(1, 1);
pq.Enqueue(2, 2);
int top = pq.Dequeue();
4. 樹 (Tree)
二叉樹遍歷 (Binary Tree Traversal)
模板:二叉樹的前序遍歷
public IList<int> PreorderTraversal(TreeNode root) {
List<int> result = new List<int>();
PreorderHelper(root, result);
return result;
}
private void PreorderHelper(TreeNode node, List<int> result) {
if (node == null) return;
result.Add(node.val);
PreorderHelper(node.left, result);
PreorderHelper(node.right, result);
}
二叉搜尋樹 (Binary Search Tree)
模板:驗證二叉搜尋樹
public bool IsValidBST(TreeNode root) {
return Validate(root, null, null);
}
private bool Validate(TreeNode node, int? lower, int? upper) {
if (node == null) return true;
int val = node.val;
if (lower != null && val <= lower) return false;
if (upper != null && val >= upper) return false;
if (!Validate(node.right, val, upper)) return false;
if (!Validate(node.left, lower, val)) return false;
return true;
}
平衡二叉樹 (Balanced Binary Tree)
模板:判斷平衡二叉樹
public bool IsBalanced(TreeNode root) {
return CheckHeight(root) != -1;
}
private int CheckHeight(TreeNode node) {
if (node == null) return 0;
int left = CheckHeight(node.left);
if (left == -1) return -1;
int right = CheckHeight(node.right);
if (right == -1) return -1;
if (Math.Abs(left - right) > 1) return -1;
return Math.Max(left, right) + 1;
}
樹的最大/最小深度 (Max/Min Depth of Tree)
模板:二叉樹的最大深度
public int MaxDepth(TreeNode root) {
if (root == null) return 0;
int leftDepth = MaxDepth(root.left);
int rightDepth = MaxDepth(root.right);
return Math.Max(leftDepth, rightDepth) + 1;
}
樹的路徑問題 (Tree Path Problems)
模板:二叉樹的所有路徑
public IList<string> BinaryTreePaths(TreeNode root) {
List<string> paths = new List<string>();
if (root == null) return paths;
if (root.left == null && root.right == null) paths.Add(root.val.ToString());
if (root.left != null) foreach (var path in BinaryTreePaths(root.left)) paths.Add(root.val + "->" + path);
if (root.right != null) foreach (var path in BinaryTreePaths(root.right)) paths.Add(root.val + "->" + path);
return paths;
}
5. 圖 (Graph)
圖的遍歷 (Graph Traversal: DFS and BFS)
模板:深度優先搜尋
public void DFS(int[,] graph, int start) {
bool[] visited = new bool[graph.GetLength(0)];
Stack<int> stack = new Stack<int>();
stack.Push(start);
while (stack.Count > 0) {
int node = stack.Pop();
if (!visited[node]) {
visited[node] = true;
Console.WriteLine($"Visited {node}");
for (int i = 0; i < graph.GetLength(1); i++) {
if (graph[node, i] == 1 && !visited[i]) {
stack.Push(i);
}
}
}
}
}
模板:廣度優先搜尋
public void BFS(int[,] graph, int start) {
bool[] visited = new bool[graph.GetLength(0)];
Queue<int> queue = new Queue<int>();
queue.Enqueue(start);
visited[start] = true;
while (queue.Count > 0) {
int node = queue.Dequeue();
Console.WriteLine($"Visited {node}");
for (int i = 0; i < graph.GetLength(1); i++) {
if (graph[node, i] == 1 && !visited[i]) {
queue.Enqueue(i);
visited[i] = true;
}
}
}
}
最短路徑 (Shortest Path)
模板:Dijkstra演算法
public int[] Dijkstra(int[,] graph, int start) {
int n = graph.GetLength(0);
int[] dist = new int[n];
bool[] visited = new bool[n];
for (int i = 0; i < n; i++) dist[i] = int.MaxValue;
dist[start] = 0;
for (int i = 0; i < n; i++) {
int u = -1;
for (int j = 0; j < n; j++) {
if (!visited[j] && (u == -1 || dist[j] < dist[u])) {
u = j;
}
}
if (dist[u] == int.MaxValue) break;
visited[u] = true;
for (int v = 0; v < n; v++) {
if (!visited[v] && graph[u, v] != 0 && dist[u] + graph[u, v] < dist[v]) {
dist[v] = dist[u] + graph[u, v];
}
}
}
return dist;
}
拓撲排序 (Topological Sorting)
模板:Kahn's演算法
public List<int> TopologicalSort(int[,] graph) {
int n = graph.GetLength(0);
int[] inDegree = new int[n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (graph[i, j] != 0) inDegree[j]++;
}
}
Queue<int> queue = new Queue<int>();
for (int i = 0; i < n; i++) {
if (inDegree[i] == 0) queue.Enqueue(i);
}
List<int> topOrder = new List<int>();
while (queue.Count > 0) {
int node = queue.Dequeue();
topOrder.Add(node);
for (int i = 0; i < n; i++) {
if (graph[node, i] != 0) {
inDegree[i]--;
if (inDegree[i] == 0) queue.Enqueue(i);
}
}
}
return topOrder;
}
連通分量 (Connected Components)
模板:使用DFS尋找連通分量
public int CountConnectedComponents(int[,] graph) {
int n = graph.GetLength(0);
bool[] visited = new bool[n];
int count = 0;
for (int i = 0; i < n; i++) {
if (!visited[i]) {
DFS(graph, i, visited);
count++;
}
}
return count;
}
private void DFS(int[,] graph, int node, bool[] visited) {
Stack<int> stack = new Stack<int>();
stack.Push(node);
while (stack.Count > 0) {
int u = stack.Pop();
if (!visited[u]) {
visited[u] = true;
for (int v = 0; v < graph.GetLength(1); v++) {
if (graph[u, v] == 1 && !visited[v]) {
stack.Push(v);
}
}
}
}
}
題目型別類
1. 排序與搜尋 (Sorting and Searching)
經典排序演算法 (Classic Sorting Algorithms: Quick Sort, Merge Sort, etc.)
模板:快速排序
public void QuickSort(int[] nums, int left, int right) {
if (left < right) {
int pivotIndex = Partition(nums, left, right);
QuickSort(nums, left, pivotIndex - 1);
QuickSort(nums, pivotIndex + 1, right);
}
}
private int Partition(int[] nums, int left, int right) {
int pivot = nums[right];
int i = left - 1;
for (int j = left; j < right; j++) {
if (nums[j] < pivot) {
i++;
Swap(nums, i, j);
}
}
Swap(nums, i + 1, right);
return i + 1;
}
private void Swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
二分查詢 (Binary Search)
模板:二分查詢
public int BinarySearch(int[] nums, int target) {
int left = 0, right = nums.Length - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] == target) return mid;
if (nums[mid] < target) left = mid + 1;
else right = mid - 1;
}
return -1;
}
快速選擇 (Quick Select)
模板:快速選擇
public int QuickSelect(int[] nums, int k) {
return QuickSelect(nums, 0, nums.Length - 1, k - 1);
}
private int QuickSelect(int[] nums, int left, int right, int k) {
if (left == right) return nums[left];
int pivotIndex = Partition(nums, left, right);
if (k == pivotIndex) return nums[k];
else if (k < pivotIndex) return QuickSelect(nums, left, pivotIndex - 1, k);
else return QuickSelect(nums, pivotIndex + 1, right, k);
}
private int Partition(int[] nums, int left, int right) {
int pivot = nums[right];
int i = left;
for (int j = left; j < right; j++) {
if (nums[j] < pivot) {
Swap(nums, i, j);
i++;
}
}
Swap(nums, i, right);
return i;
}
private void Swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
2. 動態規劃 (Dynamic Programming)
斐波那契數列 (Fibonacci Sequence)
模板:斐波那契數列
public int Fib(int n) {
if (n <= 1) return n;
int[] dp = new int[n + 1];
dp[0] = 0;
dp[1] = 1;
for (int i = 2; i <= n; i++) {
dp[i] = dp[i - 1] + dp[i - 2];
}
return dp[n];
}
揹包問題 (Knapsack Problem)
模板:0-1揹包問題
public int Knapsack(int[] weights, int[] values, int capacity) {
int n = weights.Length;
int[,] dp = new int[n + 1, capacity + 1];
for (int i = 1; i <= n; i++) {
for (int w = 1; w <= capacity; w++) {
if (weights[i - 1] <= w) {
dp[i, w] = Math.Max(dp[i - 1, w], dp[i - 1, w - weights[i - 1]] + values[i - 1]);
} else {
dp[i, w] = dp[i - 1, w];
}
}
}
return dp[n, capacity];
}
最長公共子序列 (Longest Common Subsequence)
模板:最長公共子序列
public int LongestCommonSubsequence(string text1, string text2) {
int m = text1.Length;
int k = text2.Length;
int[,] dp = new int[m + 1, k + 1];
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= k; j++) {
if (text1[i - 1] == text2[j - 1]) {
dp[i, j] = dp[i - 1, j - 1] + 1;
} else {
dp[i, j] = Math.Max(dp[i - 1, j], dp[i, j - 1]);
}
}
}
return dp[m, k];
}
最長遞增子序列 (Longest Increasing Subsequence)
模板:最長遞增子序列
public int LengthOfLIS(int[] nums) {
if (nums.Length == 0) return 0;
int[] dp = new int[nums.Length];
int maxLen = 1;
for (int i = 0; i < nums.Length; i++) {
dp[i] = 1;
for (int j = 0; j < i; j++) {
if (nums[i] > nums[j]) {
dp[i] = Math.Max(dp[i], dp[j] + 1);
}
}
maxLen = Math.Max(maxLen, dp[i]);
}
return maxLen;
}
3. 回溯法 (Backtracking)
排列與組合 (Permutations and Combinations)
模板:全排列
public IList<IList<int>> Permute(int[] nums) {
List<IList<int>> res = new List<IList<int>>();
bool[] used = new bool[nums.Length];
Backtrack(nums, new List<int>(), used, res);
return res;
}
private void Backtrack
(int[] nums, List<int> tempList, bool[] used, List<IList<int>> res) {
if (tempList.Count == nums.Length) {
res.Add(new List<int>(tempList));
} else {
for (int i = 0; i < nums.Length; i++) {
if (used[i]) continue;
used[i] = true;
tempList.Add(nums[i]);
Backtrack(nums, tempList, used, res);
used[i] = false;
tempList.RemoveAt(tempList.Count - 1);
}
}
}
子集 (Subsets)
模板:子集
public IList<IList<int>> Subsets(int[] nums) {
List<IList<int>> res = new List<IList<int>>();
Backtrack(nums, 0, new List<int>(), res);
return res;
}
private void Backtrack(int[] nums, int start, List<int> tempList, List<IList<int>> res) {
res.Add(new List<int>(tempList));
for (int i = start; i < nums.Length; i++) {
tempList.Add(nums[i]);
Backtrack(nums, i + 1, tempList, res);
tempList.RemoveAt(tempList.Count - 1);
}
}
八皇后問題 (N-Queens)
模板:八皇后問題
public IList<IList<string>> SolveNQueens(int n) {
List<IList<string>> res = new List<IList<string>>();
char[][] board = new char[n][];
for (int i = 0; i < n; i++) {
board[i] = new char[n];
Array.Fill(board[i], '.');
}
Backtrack(board, 0, res);
return res;
}
private void Backtrack(char[][] board, int row, List<IList<string>> res) {
if (row == board.Length) {
List<string> tempList = new List<string>();
foreach (var r in board) {
tempList.Add(new string(r));
}
res.Add(tempList);
} else {
for (int col = 0; col < board.Length; col++) {
if (IsValid(board, row, col)) {
board[row][col] = 'Q';
Backtrack(board, row + 1, res);
board[row][col] = '.';
}
}
}
}
private bool IsValid(char[][] board, int row, int col) {
for (int i = 0; i < row; i++) {
if (board[i][col] == 'Q') return false;
}
for (int i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) {
if (board[i][j] == 'Q') return false;
}
for (int i = row - 1, j = col + 1; i >= 0 && j < board.Length; i--, j++) {
if (board[i][j] == 'Q') return false;
}
return true;
}
4. 貪心演算法 (Greedy Algorithm)
區間排程 (Interval Scheduling)
模板:區間排程問題
public int IntervalSchedule(int[][] intervals) {
if (intervals.Length == 0) return 0;
Array.Sort(intervals, (a, b) => a[1].CompareTo(b[1]));
int end = intervals[0][1];
int count = 1;
for (int i = 1; i < intervals.Length; i++) {
if (intervals[i][0] >= end) {
end = intervals[i][1];
count++;
}
}
return count;
}
跳躍遊戲 (Jump Game)
模板:跳躍遊戲
public bool CanJump(int[] nums) {
int maxReach = 0;
for (int i = 0; i < nums.Length; i++) {
if (i > maxReach) return false;
maxReach = Math.Max(maxReach, i + nums[i]);
}
return true;
}
分配問題 (Assignment Problem)
模板:分配問題
public int AssignCookies(int[] g, int[] s) {
Array.Sort(g);
Array.Sort(s);
int i = 0, j = 0;
while (i < g.Length && j < s.Length) {
if (g[i] <= s[j]) i++;
j++;
}
return i;
}
5. 位運算 (Bit Manipulation)
基本位操作 (Basic Bit Operations)
模板:位操作模板
// 獲取整數的二進位制表示中1的個數
public int HammingWeight(uint n) {
int count = 0;
while (n != 0) {
count++;
n &= (n - 1);
}
return count;
}
異或操作 (XOR Operation)
模板:找出陣列中唯一的一個重複數字
public int SingleNumber(int[] nums) {
int result = 0;
foreach (var num in nums) {
result ^= num;
}
return result;
}