栈是一种**后进先出(LIFO,Last In First Out)**的数据结构。插入和删除操作只能在栈顶进行。
操作 | 时间复杂度 |
---|---|
入栈(push) | O ( 1 ) O(1) O(1) |
出栈(pop) | O ( 1 ) O(1) O(1) |
访问栈顶元素 | O ( 1 ) O(1) O(1) |
问题描述:给定一个只包含 (
和 )
的字符串,判断括号是否匹配。
C++实现:
#include
#include
using namespace std;
bool isValid(string s) {
stack<char> stk;
for (char c : s) {
if (c == '(') {
stk.push(c);
} else {
if (stk.empty() || stk.top() != '(') {
return false;
}
stk.pop();
}
}
return stk.empty();
}
int main() {
string s = "(())";
cout << (isValid(s) ? "Valid" : "Invalid") << endl;
return 0;
}
Python实现:
def is_valid(s):
stack = []
for c in s:
if c == '(':
stack.append(c)
else:
if not stack or stack[-1] != '(':
return False
stack.pop()
return len(stack) == 0
s = "(())"
print("Valid" if is_valid(s) else "Invalid")
Java实现:
import java.util.Stack;
public class Main {
public static boolean isValid(String s) {
Stack<Character> stack = new Stack<>();
for (char c : s.toCharArray()) {
if (c == '(') {
stack.push(c);
} else {
if (stack.isEmpty() || stack.peek() != '(') {
return false;
}
stack.pop();
}
}
return stack.isEmpty();
}
public static void main(String[] args) {
String s = "(())";
System.out.println(isValid(s) ? "Valid" : "Invalid");
}
}
队列是一种**先进先出(FIFO,First In First Out)**的数据结构,插入操作在队尾,删除操作在队首。
操作 | 时间复杂度 |
---|---|
入队 | O ( 1 ) O(1) O(1) |
出队 | O ( 1 ) O(1) O(1) |
问题描述:按层序输出二叉树的节点值。
C++实现:
#include
#include
#include
using namespace std;
struct TreeNode {
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> result;
if (!root) return result;
queue<TreeNode*> q;
q.push(root);
while (!q.empty()) {
int size = q.size();
vector<int> level;
for (int i = 0; i < size; ++i) {
TreeNode* node = q.front(); q.pop();
level.push_back(node->val);
if (node->left) q.push(node->left);
if (node->right) q.push(node->right);
}
result.push_back(level);
}
return result;
}
int main() {
TreeNode* root = new TreeNode(1);
root->left = new TreeNode(2);
root->right = new TreeNode(3);
vector<vector<int>> result = levelOrder(root);
for (const auto& level : result) {
for (int val : level) {
cout << val << " ";
}
cout << endl;
}
return 0;
}
Python实现:
from collections import deque
def level_order(root):
if not root:
return []
result, queue = [], deque([root])
while queue:
level = []
for _ in range(len(queue)):
node = queue.popleft()
level.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
result.append(level)
return result
# TreeNode class definition
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
root = TreeNode(1)
root.left = TreeNode(2)
root.right = TreeNode(3)
print(level_order(root))
Java实现:
import java.util.*;
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
public class Main {
public static List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> result = new ArrayList<>();
if (root == null) return result;
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
int size = queue.size();
List<Integer> level = new ArrayList<>();
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();
level.add(node.val);
if (node.left != null) queue.offer(node.left);
if (node.right != null) queue.offer(node.right);
}
result.add(level);
}
return result;
}
public static void main(String[] args) {
TreeNode root = new TreeNode(1);
root.left = new TreeNode(2);
root.right = new TreeNode(3);
System.out.println(levelOrder(root));
}
}
堆是一种基于树的数据结构,分为最大堆和最小堆:
通常使用堆实现一些需要自动索引的场景,如优先队列。
操作 | 时间复杂度 |
---|---|
插入(insert) | O ( log n ) O(\log n) O(logn) |
删除(delete) | O ( log n ) O(\log n) O(logn) |
取最大/最小值 | O ( 1 ) O(1) O(1) |
问题描述:给定一个数组,找到其中前 K 个最大元素。
C++实现:
#include
#include
#include
using namespace std;
vector<int> topKElements(vector<int>& nums, int k) {
priority_queue<int, vector<int>, greater<int>> minHeap;
for (int num : nums) {
minHeap.push(num);
if (minHeap.size() > k) {
minHeap.pop();
}
}
vector<int> result;
while (!minHeap.empty()) {
result.push_back(minHeap.top());
minHeap.pop();
}
return result;
}
int main() {
vector<int> nums = {3, 2, 1, 5, 6, 4};
int k = 2;
vector<int> result = topKElements(nums, k);
for (int val : result) {
cout << val << " ";
}
cout << endl;
return 0;
}
Python实现:
import heapq
def top_k_elements(nums, k):
return heapq.nlargest(k, nums)
nums = [3, 2, 1, 5, 6, 4]
k = 2
print(top_k_elements(nums, k))
Java实现:
import java.util.*;
public class Main {
public static List<Integer> topKElements(int[] nums, int k) {
PriorityQueue<Integer> minHeap = new PriorityQueue<>();
for (int num : nums) {
minHeap.offer(num);
if (minHeap.size() > k) {
minHeap.poll();
}
}
List<Integer> result = new ArrayList<>(minHeap);
Collections.sort(result, Collections.reverseOrder());
return result;
}
public static void main(String[] args) {
int[] nums = {3, 2, 1, 5, 6, 4};
int k = 2;
System.out.println(topKElements(nums, k));
}
}
下面是并查集和树状数组的内容,整合到现有文档中:
并查集是一种用于处理动态连通性问题的数据结构,主要支持以下两种操作:
操作 | 时间复杂度 |
---|---|
查找 | O ( l o g ( n ) ) O(log(n)) O(log(n)) |
合并 | O ( l o g ( n ) ) O(log(n)) O(log(n)) |
问题描述:给定包含 n
个节点的无向图,以及一些边,判断图是否是连通的。
C++实现:
#include
#include
using namespace std;
class UnionFind {
public:
UnionFind(int n) : parent(n), rank(n, 1) {
for (int i = 0; i < n; ++i) parent[i] = i;
}
int find(int x) {
if (x != parent[x]) {
parent[x] = find(parent[x]); // 路径压缩
}
return parent[x];
}
void unionSet(int x, int y) {
int rootX = find(x);
int rootY = find(y);
if (rootX != rootY) {
if (rank[rootX] > rank[rootY]) {
parent[rootY] = rootX;
} else if (rank[rootX] < rank[rootY]) {
parent[rootX] = rootY;
} else {
parent[rootY] = rootX;
rank[rootX]++;
}
}
}
private:
vector<int> parent, rank;
};
int main() {
UnionFind uf(5);
uf.unionSet(0, 1);
uf.unionSet(1, 2);
cout << (uf.find(0) == uf.find(2) ? "Connected" : "Not Connected") << endl;
return 0;
}
Python实现:
class UnionFind:
def __init__(self, n):
self.parent = list(range(n))
self.rank = [1] * n
def find(self, x):
if x != self.parent[x]:
self.parent[x] = self.find(self.parent[x]) # 路径压缩
return self.parent[x]
def union(self, x, y):
rootX = self.find(x)
rootY = self.find(y)
if rootX != rootY:
if self.rank[rootX] > self.rank[rootY]:
self.parent[rootY] = rootX
elif self.rank[rootX] < self.rank[rootY]:
self.parent[rootX] = rootY
else:
self.parent[rootY] = rootX
self.rank[rootX] += 1
uf = UnionFind(5)
uf.union(0, 1)
uf.union(1, 2)
print("Connected" if uf.find(0) == uf.find(2) else "Not Connected")
Java实现:
class UnionFind {
private int[] parent;
private int[] rank;
public UnionFind(int n) {
parent = new int[n];
rank = new int[n];
for (int i = 0; i < n; i++) {
parent[i] = i;
rank[i] = 1;
}
}
public int find(int x) {
if (x != parent[x]) {
parent[x] = find(parent[x]); // 路径压缩
}
return parent[x];
}
public void union(int x, int y) {
int rootX = find(x);
int rootY = find(y);
if (rootX != rootY) {
if (rank[rootX] > rank[rootY]) {
parent[rootY] = rootX;
} else if (rank[rootX] < rank[rootY]) {
parent[rootX] = rootY;
} else {
parent[rootY] = rootX;
rank[rootX]++;
}
}
}
}
public class Main {
public static void main(String[] args) {
UnionFind uf = new UnionFind(5);
uf.union(0, 1);
uf.union(1, 2);
System.out.println(uf.find(0) == uf.find(2) ? "Connected" : "Not Connected");
}
}
树状数组是一种用于高效维护数组前缀和的数据结构,支持快速更新和查询操作。
操作 | 时间复杂度 |
---|---|
单点更新 | O ( log n ) O(\log n) O(logn) |
前缀查询 | O ( log n ) O(\log n) O(logn) |
问题描述:支持动态更新和快速前缀和查询。
C++实现:
#include
#include
using namespace std;
class FenwickTree {
public:
FenwickTree(int n) : tree(n + 1, 0) {}
void update(int i, int delta) {
while (i < tree.size()) {
tree[i] += delta;
i += i & -i;
}
}
int query(int i) {
int sum = 0;
while (i > 0) {
sum += tree[i];
i -= i & -i;
}
return sum;
}
private:
vector<int> tree;
};
int main() {
FenwickTree ft(5);
ft.update(1, 5);
ft.update(2, 3);
cout << ft.query(2) << endl; // 输出8
return 0;
}
Python实现:
class FenwickTree:
def __init__(self, n):
self.tree = [0] * (n + 1)
def update(self, i, delta):
while i < len(self.tree):
self.tree[i] += delta
i += i & -i
def query(self, i):
sum_ = 0
while i > 0:
sum_ += self.tree[i]
i -= i & -i
return sum_
ft = FenwickTree(5)
ft.update(1, 5)
ft.update(2, 3)
print(ft.query(2)) # 输出8
Java实现:
class FenwickTree {
private int[] tree;
public FenwickTree(int n) {
tree = new int[n + 1];
}
public void update(int i, int delta) {
while (i < tree.length) {
tree[i] += delta;
i += i & -i;
}
}
public int query(int i) {
int sum = 0;
while (i > 0) {
sum += tree[i];
i -= i & -i;
}
return sum;
}
public static void main(String[] args) {
FenwickTree ft = new FenwickTree(5);
ft.update(1, 5);
ft.update(2, 3);
System.out.println(ft.query(2)); // 输出8
}
}