📅  最后修改于: 2023-12-03 15:41:06.422000             🧑  作者: Mango
竞争性编程是一种以赛制为主的编程比赛,常常用于测试程序员们的编程技巧和算法能力。在这种比赛中,时间和空间复杂度往往是决定胜负的关键因素。因此,掌握一些基本的算法和数据结构是非常重要的。下面介绍竞争性编程中最常用的十大算法和数据结构。
在竞争性编程中,时间复杂度是非常重要的。因此,排序算法是必不可少的一个部分。最常用的排序算法有冒泡排序、选择排序、插入排序、归并排序和快速排序。这些排序算法的时间复杂度分别为O(n^2)、O(n^2)、O(n^2)、O(nlogn)和O(nlogn)。
# 归并排序示例代码
def merge_sort(arr):
if len(arr) > 1:
mid = len(arr) // 2
left_half = arr[:mid]
right_half = arr[mid:]
merge_sort(left_half)
merge_sort(right_half)
i = 0
j = 0
k = 0
while i < len(left_half) and j < len(right_half):
if left_half[i] < right_half[j]:
arr[k] = left_half[i]
i += 1
else:
arr[k] = right_half[j]
j += 1
k += 1
while i < len(left_half):
arr[k] = left_half[i]
i += 1
k += 1
while j < len(right_half):
arr[k] = right_half[j]
j += 1
k += 1
哈希表是一种数据结构,可以用来存储和检索键值对。在竞争性编程中,哈希表被广泛用于对数进行计数。哈希表的时间复杂度为O(1)。
# 哈希表示例代码
table = {}
# 给哈希表添加键值对
table['apple'] = 1
table['banana'] = 2
table['orange'] = 3
# 访问哈希表的键值对
print(table['apple']) # 输出1
print(table['banana']) # 输出2
print(table['orange']) # 输出3
队列是一种基本的数据结构,可以用来实现先进先出的操作。在竞争性编程中,队列通常用于广度优先搜索的算法中。队列的时间复杂度为O(1)。
# 队列示例代码
class Queue:
def __init__(self):
self.items = []
def enqueue(self, item):
self.items.insert(0, item)
def dequeue(self):
return self.items.pop()
def is_empty(self):
return len(self.items) == 0
def size(self):
return len(self.items)
q = Queue()
q.enqueue(1)
q.enqueue(2)
q.enqueue(3)
print(q.dequeue()) # 输出1
print(q.dequeue()) # 输出2
print(q.dequeue()) # 输出3
栈是一种基本的数据结构,可以用来实现后进先出的操作。在竞争性编程中,栈通常用于深度优先搜索的算法中。栈的时间复杂度为O(1)。
# 栈示例代码
class Stack:
def __init__(self):
self.items = []
def push(self, item):
self.items.append(item)
def pop(self):
return self.items.pop()
def is_empty(self):
return len(self.items) == 0
def size(self):
return len(self.items)
s = Stack()
s.push(1)
s.push(2)
s.push(3)
print(s.pop()) # 输出3
print(s.pop()) # 输出2
print(s.pop()) # 输出1
二分查找是一种基本的搜索算法,可以在有序列表中查找特定元素。在竞争性编程中,二分查找通常用于搜索最优解等问题。二分查找的时间复杂度为O(logn)。
# 二分查找示例代码
def binary_search(arr, x):
low, high = 0, len(arr)-1
while low <= high:
mid = (low + high) // 2
if arr[mid] < x:
low = mid + 1
elif arr[mid] > x:
high = mid - 1
else:
return mid
return -1
并查集是一种用于处理集合的数据结构,可以用于动态连通性的问题。在竞争性编程中,并查集通常用于间接的查找元素。并查集的时间复杂度为O(logn)。
# 并查集示例代码
class DSU:
def __init__(self, n):
self.parent = list(range(n))
def find(self, x):
if self.parent[x] != x:
self.parent[x] = self.find(self.parent[x])
return self.parent[x]
def union(self, x, y):
self.parent[self.find(x)] = self.find(y)
dsu = DSU(5)
dsu.union(1, 2)
dsu.union(3, 4)
dsu.union(4, 1)
print(dsu.find(1)) # 输出2
print(dsu.find(3)) # 输出4
最短路算法是一种用于查找两点之间最短路径的算法。在竞争性编程中,最短路算法通常用于搜索最优解等问题。最短路算法的时间复杂度为O(E+VlogV),其中E为边数,V为顶点数。
# 最短路算法示例代码
import heapq
def dijkstra(graph, start):
distances = {v: float('infinity') for v in graph}
distances[start] = 0
pq = [(0, start)]
while pq:
current_distance, current_vertex = heapq.heappop(pq)
if current_distance > distances[current_vertex]:
continue
for neighbor, weight in graph[current_vertex].items():
distance = current_distance + weight
if distance < distances[neighbor]:
distances[neighbor] = distance
heapq.heappush(pq, (distance, neighbor))
return distances
graph = {
'A': {'B': 2, 'C': 3},
'B': {'A': 2, 'C': 1},
'C': {'A': 3, 'B': 1}
}
print(dijkstra(graph, 'A')) # 输出{'A': 0, 'B': 2, 'C': 3}
动态规划是一种算法思想,用于解决重叠子问题的最优解问题。在竞争性编程中,动态规划通常用于计算最大子序列、最长上升子序列等问题。动态规划的时间复杂度为O(n^2),其中n为问题的规模。
# 动态规划示例代码
def max_subarray(nums):
dp = [0] * len(nums)
dp[0] = nums[0]
for i in range(1, len(nums)):
dp[i] = max(nums[i], nums[i] + dp[i-1])
return max(dp)
print(max_subarray([-2,1,-3,4,-1,2,1,-5,4])) # 输出6
贪心算法是一种算法思想,用于解决最优化问题。在竞争性编程中,贪心算法通常用于计算最大价值、最小花费等问题。贪心算法的时间复杂度为O(nlogn),其中n为问题的规模。
# 贪心算法示例代码
def max_profit(prices):
profit = 0
for i in range(1, len(prices)):
if prices[i] > prices[i-1]:
profit += prices[i] - prices[i-1]
return profit
print(max_profit([7, 1, 5, 3, 6, 4])) # 输出7
分治算法是一种算法思想,用于解决子问题并组合最终答案。在竞争性编程中,分治算法通常用于计算最大子数组、最近点对等问题。分治算法的时间复杂度为O(nlogn),其中n为问题的规模。
# 分治算法示例代码
def max_subarray(nums, l, h):
if l == h:
return nums[l]
mid = (l + h) // 2
left_sum = max_subarray(nums, l, mid)
right_sum = max_subarray(nums, mid+1, h)
cross_sum = cross_subarray(nums, l, mid, h)
return max(left_sum, right_sum, cross_sum)
def cross_subarray(nums, l, mid, h):
left_sum = float('-inf')
s = 0
for i in range(mid, l-1, -1):
s += nums[i]
left_sum = max(left_sum, s)
right_sum = float('-inf')
s = 0
for i in range(mid+1, h+1):
s += nums[i]
right_sum = max(right_sum, s)
return left_sum + right_sum
arr = [-2,1,-3,4,-1,2,1,-5,4]
print(max_subarray(arr, 0, len(arr)-1)) # 输出6
以上是竞争性编程的十大算法和数据结构。掌握这些算法和数据结构可以提高你在竞争性编程中的成绩,也会使你成为一个更好的程序员。