python 算法题基础常用总结(比赛 or 机试 or 面试)

新建文件夹之后,vscode 打开文件夹;python直接右上角

g++ 1.cpp -o 1.exe ./1.exe

1. 输入

python 复制代码
# 1. 读入两个整数
n, m = map(int, input().split())

# 2. 读入一行整数
a = input().split()
a = [int(x) for x in a]
print(a[0], a[1])

# 3. 读入n行m列
n, m = map(int, input().split())
matrix = [input().split() for _ in range(n)] # n行 每行按照空格分为列表
matrix = [list(map(int, input().split())) for _ in range(n)] # 整数

2. 列表

python 复制代码
my_list = [1, 2, 3]

# 修改元素
my_list[0] = 100  # [100, 2, 3]

# 添加元素
my_list.append(4)        # [100, 2, 3, 4]
my_list.insert(1, 200)   # [100, 200, 2, 3, 4](在索引1处插入)
my_list.extend([5, 6])   # [100, 200, 2, 3, 4, 5, 6]

# 删除元素
my_list.remove(200)      # 删除第一个值为200的元素
popped = my_list.pop()   # 删除并返回最后一个元素
popped2 = my_list.pop(1) # 删除索引1的元素
del my_list[0]           # 删除索引0的元素
del my_list[1:3]         # 删除切片


# 查找元素
my_list = [1, 2, 3, 2, 4, 2]

index = my_list.index(3)     # 2(第一次出现的索引)
count = my_list.count(2)     # 3(出现次数)

3. 字典

python 复制代码
# Counter 计数
from collections import Counter
a = [1,2,3,4,5,4]
b = Counter(a)
print(b.items())
print(b.values())
print(b.keys())


# defaultdict 默认为 0 的字典,便于计数。
from collections import defaultdict
words = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple']
word_count = defaultdict(int)

for word in words:
    word_count[word] += 1

print(dict(word_count))

4. heapq 最小堆

python 复制代码
import heapq
heapq.heapify(list)
heapq.heappush(heap, item) # 添加负数,则为最大堆
heapq.heappop(heap)

5. sort 组合与按指标排序 + lambda 表达式

python 复制代码
# 先按第二个指标降序,相同时按第三个指标升序
a = sorted(zip(startTime, endTime, profit), key = lambda p:(-p[1], p[2]))

intervals.sort(key=lambda x: x[0])


# 1. 基本函数
add = lambda x, y: x + y
print(f"3 + 5 = {add(3, 5)}")  # 8

# 2. 单参数
square = lambda x: x ** 2
print(f"4的平方: {square(4)}")  # 16

# 3. 多参数
multiply = lambda a, b, c: a * b * c
print(f"2*3*4 = {multiply(2, 3, 4)}")  # 24


nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# 1. 与filter配合筛选
even_nums = list(filter(lambda x: x % 2 == 0, nums))
print("偶数:", even_nums)

# 2. 与max/min配合
max_student = max(students, key=lambda s: s[1])

# 3. 与map配合
squared_nums = list(map(lambda x: x ** 2, nums))
print("平方:", squared_nums)

# 4. 与reduce配合
from functools import reduce
product = reduce(lambda x, y: x * y, nums)
print("1到10的乘积:", product)  # 3628800

# 5. 绝对值 条件分支
abs_func = lambda x: x if x >= 0 else -x

6. 记忆化搜索 + BFS

python 复制代码
from functools import cache
@cache
def dfs(i: int, j: int, and_: int) -> int:
     if n - i < m - j:  # 剩余元素不足
         return inf
     if j == m:  # 分了 m 段
          return 0 if i == n else inf
     and_ &= nums[i]
     res = dfs(i + 1, j, and_)  # 不划分
     if and_ == andValues[j]:  # 划分,nums[i] 是这一段的最后一个数
          res = min(res, dfs(i + 1, j + 1, -1) + nums[i])
     return res
python 复制代码
from collections import deque

def bfs_grid(grid, start, target):
    rows, cols = len(grid), len(grid[0])
    directions = [(0, 1), (0, -1), (1, 0), (-1, 0)]  # 四方向
    
    queue = deque([start])
    visited = [[False] * cols for _ in range(rows)]
    visited[start[0]][start[1]] = True
    steps = 0
    
    while queue:
        size = len(queue)
        for _ in range(size):
            x, y = queue.popleft()
            
            # 到达目标
            if (x, y) == target:
                return steps
            
            # 遍历四个方向
            for dx, dy in directions:
                nx, ny = x + dx, y + dy
                
                # 检查边界和访问状态
                if 0 <= nx < rows and 0 <= ny < cols:
                    if not visited[nx][ny] and grid[nx][ny] != '#':  # # 表示障碍
                        visited[nx][ny] = True
                        queue.append((nx, ny))
        
        steps += 1
    
    return -1  # 无法到达

7. 集合

python 复制代码
my_set = {1, 2, 3}

# 添加元素
my_set.add(4)          # {1, 2, 3, 4}
my_set.add(2)          # {1, 2, 3, 4}(2已存在,无变化)
my_set.update([5, 6])  # {1, 2, 3, 4, 5, 6}(添加多个)

# 删除元素
my_set.remove(3)       # 删除3,如果不存在会报KeyError
my_set.discard(10)     # 删除10,如果不存在也不会报错

# 两个集合运算 | & - 分别为并集 交集 差集

8. 输出

python 复制代码
# 1. f-string
name = "Alice"
score = 95.5
print(f"{name}的成绩是{score:.2f}分")  # Alice的成绩是95.50分

# 2. format()方法
print("{}的成绩是{:.2f}分".format(name, score))


# 1. 一行输出数组元素,用空格分隔
arr = [1, 2, 3, 4, 5]

# 方法1:join + map
print(" ".join(map(str, arr)))  # 1 2 3 4 5

# 方法2:列表推导式
print(" ".join([str(x) for x in arr]))


# 标准矩阵格式
matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

for row in matrix:
    print(" ".join(map(str, row)))

9. 二进制

python 复制代码
bin(num)[2:] # 二进制字符串
n & (n - 1) # 清除最低位的1
n & -n # 获取最低位的1  因为补码取反+1,只有最低位的 两个都是1

10. bisect 二分查找

python 复制代码
import bisect

arr = [1, 3, 3, 5, 7, 9, 11]

# 1. bisect_left - 找到第一个 >= x 的位置
pos1 = bisect.bisect_left(arr, 3)
print("bisect_left(3):", pos1)  # 1 (第一个3的位置)

# 2. bisect_right / bisect - 找到第一个 > x 的位置
pos2 = bisect.bisect_right(arr, 3)
print("bisect_right(3):", pos2)  # 3 (最后一个3之后的位置)

结构体 类的排序查找。

python 复制代码
class Student:
    def __init__(self, name, score):
        self.name = name
        self.score = score

students = [
    Student('Alice', 85),
    Student('Bob', 92),
    Student('Charlie', 78),
    Student('David', 92)  # 相同分数
]

# 按分数排序
students.sort(key=lambda s: s.score)

# 查找分数 >= 90 的第一个学生
index = bisect.bisect_left([s.score for s in students], 90)
print(f"第一个分数>=90的学生: {students[index] if index < len(students) else None}")

最长递增子序列(LIS)的O(nlogn)解法

python 复制代码
def lis_length(nums):
    """返回最长递增子序列的长度"""
    tails = []  # tails[i]表示长度为i+1的LIS的最小结尾值
    
    for num in nums:
        # 找到第一个 >= num 的位置
        pos = bisect.bisect_left(tails, num)
        if pos == len(tails):
            tails.append(num)  # 可以延长LIS
        else:
            tails[pos] = num  # 替换掉更大的结尾值
    
    return len(tails)

nums = [10, 9, 2, 5, 3, 7, 101, 18]
print(f"LIS长度: {lis_length(nums)}")  # 4

11. 最短路 + 最小生成树

dijkstra

python 复制代码
import heapq

def dijkstra(n, edges, start):
    """邻接表,返回从start到所有点的最短距离"""
    g = [[] for _ in range(n)]
    for u, v, w in edges:
        g[u].append((v, w))
        # 如果是无向图: g[v].append((u, w))
    
    dist = [float('inf')] * n
    dist[start] = 0
    pq = [(0, start)]
    
    while pq:
        d, u = heapq.heappop(pq)
        if d > dist[u]:
            continue
        for v, w in g[u]:
            nd = d + w
            if nd < dist[v]:
                dist[v] = nd
                heapq.heappush(pq, (nd, v))
    return dist

Floyd

python 复制代码
def floyd(n, edges):
    """邻接矩阵,返回所有点对的最短距离"""
    INF = 10**9
    dist = [[INF] * n for _ in range(n)]
    for i in range(n):
        dist[i][i] = 0
    for u, v, w in edges:
        dist[u][v] = min(dist[u][v], w)  # 处理重边
    
    for k in range(n):
        for i in range(n):
            if dist[i][k] == INF:
                continue
            for j in range(n):
                if dist[k][j] == INF:
                    continue
                dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j])
    return dist

Kruskal

python 复制代码
def kruskal(n, edges):
    """返回最小生成树的权重和边列表"""
    edges.sort(key=lambda x: x[2])  # 按权重排序
    
    parent = list(range(n))
    def find(x):
        if parent[x] != x:
            parent[x] = find(parent[x])
        return parent[x]
    
    def union(x, y):
        rx, ry = find(x), find(y)
        if rx == ry:
            return False
        parent[ry] = rx
        return True
    
    weight = 0
    mst = []
    for u, v, w in edges:
        if union(u, v):
            weight += w
            mst.append((u, v, w))
            if len(mst) == n - 1:
                break
    return weight, mst

Prim

python 复制代码
import heapq

def prim(n, edges):
    """邻接表,返回最小生成树的权重"""
    g = [[] for _ in range(n)]
    for u, v, w in edges:
        g[u].append((v, w))
        g[v].append((u, w))
    
    visited = [False] * n
    heap = [(0, 0)]  # (weight, node)
    weight = 0
    
    while heap:
        w, u = heapq.heappop(heap)
        if visited[u]:
            continue
        visited[u] = True
        weight += w
        for v, cost in g[u]:
            if not visited[v]:
                heapq.heappush(heap, (cost, v))
    
    return weight

12. 字符串

python 复制代码
s = "hello world hello"

# 查找
print(s.find("lo"))        # 3 (第一次出现位置)
print(s.rfind("lo"))       # 14 (最后一次出现位置)
# 检查
print("123".isdigit())     # True
print("abc".isalpha())     # True
print("abc123".isalnum())  # True
# 去除指定字符
s = "  hello world  \n"
print(s.strip())      # "hello world"
print(s.lstrip())     # "hello world  \n"
print(s.rstrip())     # "  hello world"

s = "**hello**"
print(s.strip("*"))   # "hello"
相关推荐
Deng8723473481 小时前
自动化极验3点选验证码的识别与验证方案
运维·python·自动化
川石课堂软件测试1 小时前
自动化测试的基本概念及常用框架
数据库·python·功能测试·测试工具·单元测试·自动化·流程图
灰勒塔德1 小时前
jetson orin nano super开发指南
linux·服务器·python
8278209372 小时前
python scp 备份
开发语言·python
poggioxay2 小时前
JAVA零基础入门知识3(持续更新中)
java·开发语言·python
serve the people2 小时前
TensorFlow 基础训练循环(简化版 + 补全代码)
人工智能·python·tensorflow
木里先森2 小时前
解决报错:/lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.32‘ not found
linux·python
爱打代码的小林2 小时前
numpy库数组笔记
笔记·python·numpy
Misnice2 小时前
pip 查看当前包列表
windows·python·pip