diff --git a/Contents/00.Introduction/02.Algorithm-Complexity.md b/Contents/00.Introduction/02.Algorithm-Complexity.md index 1221ac3e..a8516d7c 100644 --- a/Contents/00.Introduction/02.Algorithm-Complexity.md +++ b/Contents/00.Introduction/02.Algorithm-Complexity.md @@ -45,10 +45,10 @@ ```Python def algorithm(n): - fact = 1 - for i in range(1, n + 1): - fact *= i - return fact + fact = 1 + for i in range(1, n + 1): + fact *= i + return fact ``` 把上述算法中所有语句的执行次数加起来 $1 + n + n + 1 = 2n + 2$,可以用一个函数 $f(n)$ 来表达语句的执行次数:$f(n) = 2n + 2$。 @@ -122,10 +122,10 @@ $O(1)$ 只是常数阶时间复杂度的一种表示方式,并不是指只执 ```Python def algorithm(n): - a = 1 - b = 2 - res = a * b + n - return res + a = 1 + b = 2 + res = a * b + n + return res ``` 上述代码虽然有 4 行,但时间复杂度也是 $O(1)$,而不是 $O(3)$。 @@ -136,10 +136,10 @@ def algorithm(n): ```Python def algorithm(n): - sum = 0 - for i in range(n): - sum += 1 - return sum + sum = 0 + for i in range(n): + sum += 1 + return sum ``` 上述代码中 `sum += 1` 的执行次数为 n 次,所以这段代码的时间复杂度为 $O(n)$。 @@ -151,11 +151,11 @@ def algorithm(n): ```Python def algorithm(n): - res = 0 - for i in range(n): - for j in range(n): - res += 1 - return res + res = 0 + for i in range(n): + for j in range(n): + res += 1 + return res ``` 上述代码中,`res += 1` 在两重循环中,根据时间复杂度的乘法原理,这段代码的执行次数为 $n^2$ 次,所以其时间复杂度为 $O(n^2)$。 @@ -166,9 +166,9 @@ def algorithm(n): ```Python def algorithm(n): - if n <= 0: - return 1 - return n * algorithm(n - 1) + if n <= 0: + return 1 + return n * algorithm(n - 1) ``` 上述代码中计算阶乘使用了递归的方法。计算 `n` 的阶乘时需要先计算出 `n - 1` 的阶乘,计算 `n - 1` 的阶乘时,需要计算出 `n - 2` 的阶乘,以此类推。在计算总的时间复杂度时需要将每一步的基本操作数相乘,即:$n * (n - 1) * (n - 2) * ... * 2 * 1 = n!$,这段代码的执行次数为 $n!$ 次,所以其时间复杂度为 $O(n!)$。 @@ -179,10 +179,10 @@ def algorithm(n): ```Python def algorithm(n): - cnt = 1 - while cnt < n: - cnt *= 2 - return cnt + cnt = 1 + while cnt < n: + cnt *= 2 + return cnt ``` 上述代码中 `cnt = 1` 的时间复杂度为 O(1) 可以忽略不算。while 循环体中 `cnt` 从 1 开始,每循环一次都乘以 2。当大于 n 时循环结束。变量 `cnt` 的取值是一个等比数列:$2^0,2^1,2^2,…,2^x$,根据 $2^x = n$,可以得出这段循环体的执行次数为 $log_2n$。所以这段代码的时间复杂度为 $O(log_2n)$。 @@ -194,13 +194,13 @@ def algorithm(n): ```Python def algorithm(n): - cnt = 1 - res = 0 - while cnt < n: - cnt *= 2 - for i in range(n): - res += 1 - return res + cnt = 1 + res = 0 + while cnt < n: + cnt *= 2 + for i in range(n): + res += 1 + return res ``` 上述代码中外层循环的时间复杂度为 $O(log_2 n)$,内层循环的时间复杂度为 $O(n)$,且两层循环相互独立,则总体时间复杂度为 $O(n log_2 n)$。 @@ -222,12 +222,12 @@ def algorithm(n): ```Python def find(nums, val): - pos = -1 - for i in range(n): - if nums[i] == val: - pos = i - break - return pos + pos = -1 + for i in range(n): + if nums[i] == val: + pos = i + break + return pos ``` 这段代码要实现的功能是:从一个整数数组 `nums` 中查找值为 `val` 的变量出现的位置。如果不考虑 `break` 语句,根据「2.3 时间复杂度计算」中讲的分析步骤,这个算法的时间复杂度是 $O(n)$,其中 n 代表数组的长度。 @@ -260,10 +260,10 @@ def find(nums, val): ```Python def algorithm(n): - a = 1 - b = 2 - res = a * b + n - return res + a = 1 + b = 2 + res = a * b + n + return res ``` 上述代码中使用 `a`、`b`、`res` 3 个局部变量,其所占空间大小并不会随着问题规模 n 的在增大而增大,所以该算法的空间复杂度为 $O(1)$。 @@ -272,9 +272,9 @@ def algorithm(n): ```Python def algorithm(n): - if n <= 0: - return 1 - return n * algorithm(n - 1) + if n <= 0: + return 1 + return n * algorithm(n - 1) ``` 上述代码采用了递归调用的方式。每次递归调用都占用了 1 个栈帧空间,总共调用了 n 次,所以该算法的空间复杂度为 $O(n)$。 diff --git a/Contents/01.Array/01.Array-Basic/01.Array-Basic.md b/Contents/01.Array/01.Array-Basic/01.Array-Basic.md index a8e3d2bd..10b6c866 100644 --- a/Contents/01.Array/01.Array-Basic/01.Array-Basic.md +++ b/Contents/01.Array/01.Array-Basic/01.Array-Basic.md @@ -83,9 +83,9 @@ arr = ['python', 'java', ['asp', 'php'], 'c'] ```Python # 从数组 nums 中读取下标为 i 的数据元素值 def value(nums, i): - if 0 <= i <= len(nums) - 1: - print(nums[i]) - + if 0 <= i <= len(nums) - 1: + print(nums[i]) + arr = [0, 5, 2, 3, 7, 1, 6] value(arr, 3) ``` diff --git a/Contents/01.Array/03.Array-Binary-Search/01.Array-Binary-Search.md b/Contents/01.Array/03.Array-Binary-Search/01.Array-Binary-Search.md index 5a7d26e5..226d948f 100644 --- a/Contents/01.Array/03.Array-Binary-Search/01.Array-Binary-Search.md +++ b/Contents/01.Array/03.Array-Binary-Search/01.Array-Binary-Search.md @@ -115,8 +115,8 @@ class Solution: ````Python # ... while left < right: - # ... - return left if nums[left] == target else -1 + # ... + return left if nums[left] == target else -1 ```` 此外,用 `left < right` 的话还有一个好处,就是退出循环的时候 `left == right` 成立,就不用判断应该返回 `left` 还是 `right` 了。 diff --git a/Contents/01.Array/04.Array-Two-Pointers/01.Array-Two-Pointers.md b/Contents/01.Array/04.Array-Two-Pointers/01.Array-Two-Pointers.md index ee9a5526..65c072f3 100644 --- a/Contents/01.Array/04.Array-Two-Pointers/01.Array-Two-Pointers.md +++ b/Contents/01.Array/04.Array-Two-Pointers/01.Array-Two-Pointers.md @@ -215,7 +215,7 @@ class Solution: slow = 0 fast = 1 while 没有遍历完: - if 满足要求的特殊条件: + if 满足要求的特殊条件: slow += 1 fast += 1 return 合适的值 diff --git a/Contents/02.Linked-List/01.Linked-List-Basic/01.Linked-List-Basic.md b/Contents/02.Linked-List/01.Linked-List-Basic/01.Linked-List-Basic.md index 31201dee..ddb505e2 100644 --- a/Contents/02.Linked-List/01.Linked-List-Basic/01.Linked-List-Basic.md +++ b/Contents/02.Linked-List/01.Linked-List-Basic/01.Linked-List-Basic.md @@ -57,14 +57,14 @@ ```Python # 链节点类 class ListNode: - def __init__(self, val=0, next=None): - self.val = val - self.next = next + def __init__(self, val=0, next=None): + self.val = val + self.next = next # 链表类 class LinkedList: - def __init__(self): - self.head = None + def __init__(self): + self.head = None ``` ### 2.2 建立一个线性链表 @@ -329,7 +329,7 @@ def removeInside(self, index): if not cur: return 'Error' - + del_node = cur.next cur.next = del_node.next ``` diff --git a/Contents/03.Stack/01.Stack-Basic/01.Stack-Basic.md b/Contents/03.Stack/01.Stack-Basic/01.Stack-Basic.md index 4331eea6..25b26a14 100644 --- a/Contents/03.Stack/01.Stack-Basic/01.Stack-Basic.md +++ b/Contents/03.Stack/01.Stack-Basic/01.Stack-Basic.md @@ -72,42 +72,42 @@ ```Python class Stack: - # 初始化空栈 - def __init__(self, size=100): - self.stack = [] - self.size = size - self.top = -1 - - # 判断栈是否为空 - def is_empty(self): - return self.top == -1 - - # 判断栈是否已满 - def is_full(self): - return self.top + 1 == self.size - - # 入栈操作 - def push(self, value): - if self.is_full(): - raise Exception('Stack is full') - else: - self.stack.append(value) - self.top += 1 - - # 出栈操作 - def pop(self): - if self.is_empty(): - raise Exception('Stack is empty') - else: - self.top -= 1 - self.stack.pop() - - # 获取栈顶元素 - def peek(self): - if self.is_empty(): - raise Exception('Stack is empty') - else: - return self.stack[self.top] + # 初始化空栈 + def __init__(self, size=100): + self.stack = [] + self.size = size + self.top = -1 + + # 判断栈是否为空 + def is_empty(self): + return self.top == -1 + + # 判断栈是否已满 + def is_full(self): + return self.top + 1 == self.size + + # 入栈操作 + def push(self, value): + if self.is_full(): + raise Exception('Stack is full') + else: + self.stack.append(value) + self.top += 1 + + # 出栈操作 + def pop(self): + if self.is_empty(): + raise Exception('Stack is empty') + else: + self.top -= 1 + self.stack.pop() + + # 获取栈顶元素 + def peek(self): + if self.is_empty(): + raise Exception('Stack is empty') + else: + return self.stack[self.top] ``` ### 2.3 堆栈的链式存储实现 @@ -130,40 +130,40 @@ class Stack: ```Python class Node: - def __init__(self, value): - self.value = value - self.next = None - + def __init__(self, value): + self.value = value + self.next = None + class Stack: - # 初始化空栈 - def __init__(self): - self.top = None - - # 判断栈是否为空 - def is_empty(self): - return self.top == None - - # 入栈操作 - def push(self, value): - cur = Node(value) - cur.next = self.top - self.top = cur - - # 出栈操作 - def pop(self): - if self.is_empty(): - raise Exception('Stack is empty') - else: - cur = self.top - self.top = self.top.next - del cur - - # 获取栈顶元素 - def peek(self): - if self.is_empty(): - raise Exception('Stack is empty') - else: - return self.top.value + # 初始化空栈 + def __init__(self): + self.top = None + + # 判断栈是否为空 + def is_empty(self): + return self.top == None + + # 入栈操作 + def push(self, value): + cur = Node(value) + cur.next = self.top + self.top = cur + + # 出栈操作 + def pop(self): + if self.is_empty(): + raise Exception('Stack is empty') + else: + cur = self.top + self.top = self.top.next + del cur + + # 获取栈顶元素 + def peek(self): + if self.is_empty(): + raise Exception('Stack is empty') + else: + return self.top.value ``` ## 3. 堆栈的应用 diff --git a/Contents/03.Stack/02.Stack-DFS/01.Stack-DFS.md b/Contents/03.Stack/02.Stack-DFS/01.Stack-DFS.md index 346054d9..b88bb32d 100644 --- a/Contents/03.Stack/02.Stack-DFS/01.Stack-DFS.md +++ b/Contents/03.Stack/02.Stack-DFS/01.Stack-DFS.md @@ -17,12 +17,12 @@ ```Python # 定义无向图结构 graph = { - "A": ["B", "C"], - "B": ["A", "C", "D"], - "C": ["A", "B", "D", "E"], - "D": ["B", "C", "E", "F"], - "E": ["C", "D"], - "F": ["D"] + "A": ["B", "C"], + "B": ["A", "C", "D"], + "C": ["A", "B", "D", "E"], + "D": ["B", "C", "E", "F"], + "E": ["C", "D"], + "F": ["D"] } ``` @@ -48,15 +48,15 @@ graph = { ```Python def dfs_recursive(graph, start, visited): - # 标记节点 - visited.add(start) - # 访问节点 - print(start) + # 标记节点 + visited.add(start) + # 访问节点 + print(start) - for end in graph[start]: - if end not in visited: + for end in graph[start]: + if end not in visited: # 深度优先遍历节点 - dfs_recursive(graph, end, visited) + dfs_recursive(graph, end, visited) ``` ## 4. 基于堆栈实现的深度优先搜索 @@ -75,17 +75,17 @@ def dfs_recursive(graph, start, visited): ```Python def dfs_stack(graph, start): - visited = set(start) - stack = [start] - - while stack: - node_u = stack.pop() - # 访问节点 - print(node_u) - for node_v in graph[node_u]: - if node_v not in visited: - stack.append(node_v) - visited.add(node_v) + visited = set(start) + stack = [start] + + while stack: + node_u = stack.pop() + # 访问节点 + print(node_u) + for node_v in graph[node_u]: + if node_v not in visited: + stack.append(node_v) + visited.add(node_v) ``` ## 5. 深度优先搜索应用 diff --git a/Contents/04.Queue/01.Queue-Basic/01.Queue-Basic.md b/Contents/04.Queue/01.Queue-Basic/01.Queue-Basic.md index c1bc73bd..59a248d1 100644 --- a/Contents/04.Queue/01.Queue-Basic/01.Queue-Basic.md +++ b/Contents/04.Queue/01.Queue-Basic/01.Queue-Basic.md @@ -73,50 +73,50 @@ ```Python class Queue: - # 初始化空队列 - def __init__(self, size=100): - self.size = size - self.queue = [None for _ in range(size)] - self.front = -1 - self.rear = -1 - - # 判断队列是否为空 - def is_empty(self): - return self.front == self.rear - - # 判断队列是否已满 - def is_full(self): - return self.rear + 1 == self.size - - # 入队操作 - def enqueue(self, value): - if self.is_full(): - raise Exception('Queue is full') - else: - self.rear += 1 - self.queue[self.rear] = value - - # 出队操作 - def dequeue(self): - if self.is_empty(): - raise Exception('Queue is empty') - else: - self.front += 1 - return self.queue[self.front] - - # 获取队头元素 - def front_value(self): - if self.is_empty(): - raise Exception('Queue is empty') - else: - return self.queue[self.front + 1] - + # 初始化空队列 + def __init__(self, size=100): + self.size = size + self.queue = [None for _ in range(size)] + self.front = -1 + self.rear = -1 + + # 判断队列是否为空 + def is_empty(self): + return self.front == self.rear + + # 判断队列是否已满 + def is_full(self): + return self.rear + 1 == self.size + + # 入队操作 + def enqueue(self, value): + if self.is_full(): + raise Exception('Queue is full') + else: + self.rear += 1 + self.queue[self.rear] = value + + # 出队操作 + def dequeue(self): + if self.is_empty(): + raise Exception('Queue is empty') + else: + self.front += 1 + return self.queue[self.front] + + # 获取队头元素 + def front_value(self): + if self.is_empty(): + raise Exception('Queue is empty') + else: + return self.queue[self.front + 1] + # 获取队尾元素 - def rear_value(self): - if self.is_empty(): - raise Exception('Queue is empty') - else: - return self.queue[self.rear] + def rear_value(self): + if self.is_empty(): + raise Exception('Queue is empty') + else: + return self.queue[self.rear] ``` ### 2.3 循环队列的顺序存储实现 @@ -132,13 +132,13 @@ class Queue: ```Python # 出队操作 def dequeue(self): - if self.is_empty(): - raise Exception('Queue is empty') - else: - value = self.queue[0] - for i in range(self.rear): + if self.is_empty(): + raise Exception('Queue is empty') + else: + value = self.queue[0] + for i in range(self.rear): self.queue[i] = self.queue[i + 1] - return value + return value ``` 这种情况下,队头指针似乎用不到了。因为队头指针总是在队列的第 `0` 个位置。但是因为删除操作涉及到整个队列元素的移动,所以每次删除操作的时间复杂度就从 $O(1)$ 变为了 $O(n)$。这种方式不太可取。 @@ -186,53 +186,53 @@ def dequeue(self): ```Python class Queue: - # 初始化空队列 - def __init__(self, size=100): - self.size = size + 1 - self.queue = [None for _ in range(size + 1)] - self.front = 0 - self.rear = 0 - - # 判断队列是否为空 - def is_empty(self): - return self.front == self.rear - - # 判断队列是否已满 - def is_full(self): - return (self.rear + 1) % self.size == self.front - - # 入队操作 - def enqueue(self, value): - if self.is_full(): - raise Exception('Queue is full') - else: - self.rear = (self.rear + 1) % self.size - self.queue[self.rear] = value - - # 出队操作 - def dequeue(self): - if self.is_empty(): - raise Exception('Queue is empty') - else: - self.queue[self.front] = None - self.front = (self.front + 1) % self.size - return self.queue[self.front] - - # 获取队头元素 - def front_value(self): - if self.is_empty(): - raise Exception('Queue is empty') - else: - value = self.queue[(self.front + 1) % self.size] - return value - - # 获取队尾元素 - def rear_value(self): - if self.is_empty(): - raise Exception('Queue is empty') - else: - value = self.queue[self.rear] - return value + # 初始化空队列 + def __init__(self, size=100): + self.size = size + 1 + self.queue = [None for _ in range(size + 1)] + self.front = 0 + self.rear = 0 + + # 判断队列是否为空 + def is_empty(self): + return self.front == self.rear + + # 判断队列是否已满 + def is_full(self): + return (self.rear + 1) % self.size == self.front + + # 入队操作 + def enqueue(self, value): + if self.is_full(): + raise Exception('Queue is full') + else: + self.rear = (self.rear + 1) % self.size + self.queue[self.rear] = value + + # 出队操作 + def dequeue(self): + if self.is_empty(): + raise Exception('Queue is empty') + else: + self.queue[self.front] = None + self.front = (self.front + 1) % self.size + return self.queue[self.front] + + # 获取队头元素 + def front_value(self): + if self.is_empty(): + raise Exception('Queue is empty') + else: + value = self.queue[(self.front + 1) % self.size] + return value + + # 获取队尾元素 + def rear_value(self): + if self.is_empty(): + raise Exception('Queue is empty') + else: + value = self.queue[self.rear] + return value ``` ### 2.3 队列的链式存储实现 @@ -258,53 +258,53 @@ class Queue: ```Python class Node: - def __init__(self, value): - self.value = value - self.next = None - + def __init__(self, value): + self.value = value + self.next = None + class Queue: - # 初始化空队列 - def __init__(self): - head = Node(0) - self.front = head - self.rear = head - - # 判断队列是否为空 - def is_empty(self): - return self.front == self.rear - - # 入队操作 - def enqueue(self, value): - node = Node(value) - self.rear.next = node - self.rear = node - - # 出队操作 - def dequeue(self): - if self.is_empty(): - raise Exception('Queue is empty') - else: - node = self.front.next - self.front.next = node.next - if self.rear == node: - self.rear = self.front - value = node.value - del node - return value - - # 获取队头元素 - def front_value(self): - if self.is_empty(): - raise Exception('Queue is empty') - else: - return self.front.next.value - - # 获取队尾元素 - def rear_value(self): - if self.is_empty(): - raise Exception('Queue is empty') - else: - return self.rear.value + # 初始化空队列 + def __init__(self): + head = Node(0) + self.front = head + self.rear = head + + # 判断队列是否为空 + def is_empty(self): + return self.front == self.rear + + # 入队操作 + def enqueue(self, value): + node = Node(value) + self.rear.next = node + self.rear = node + + # 出队操作 + def dequeue(self): + if self.is_empty(): + raise Exception('Queue is empty') + else: + node = self.front.next + self.front.next = node.next + if self.rear == node: + self.rear = self.front + value = node.value + del node + return value + + # 获取队头元素 + def front_value(self): + if self.is_empty(): + raise Exception('Queue is empty') + else: + return self.front.next.value + + # 获取队尾元素 + def rear_value(self): + if self.is_empty(): + raise Exception('Queue is empty') + else: + return self.rear.value ``` ## 3. 队列的应用