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"
相关推荐
API技术员8 小时前
京东API接口:如何高效获取商品详情与SKU信息
python
sort浅忆9 小时前
deeptest执行接口脚本,添加python脚本断言
开发语言·python
冷月半明9 小时前
trea solo,让我从牛马外包翻身当“甲方”
python·trae
superman超哥9 小时前
仓颉借用检查器工作原理深度解析
c语言·开发语言·c++·python·仓颉
张彦峰ZYF9 小时前
Python 项目文件组织与工程化实践
python·项目文件组织与工程化实践
webbodys10 小时前
Python文件操作与异常处理:构建健壮的应用程序
java·服务器·python
MediaTea11 小时前
Python:实例 __dict__ 详解
java·linux·前端·数据库·python
SunnyDays101111 小时前
Python Excel 打印设置全攻略(打印区域、缩放、页边距、页眉页脚等)
python·excel打印设置·excel页面设置·excel打印选项
小鸡吃米…11 小时前
Python的人工智能-机器学习
人工智能·python·机器学习
傻啦嘿哟11 小时前
Python上下文管理器:优雅处理资源释放的魔法工具
开发语言·python