蓝桥杯算法(python)

这篇博客详细介绍了蓝桥杯算法比赛的重点,包括算法复杂度、递归、数组操作、排序算法、搜索策略、数据结构如栈、队列、树和图,以及动态规划等。特别讨论了斐波那契数列、两数之和问题、二叉树遍历、深度优先搜索(DFS)、广度优先搜索(BFS)以及动态规划在背包问题和最长公共子序列问题中的应用。内容涵盖了Python实现和算法效率分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

蓝桥杯算法级别。

蓝桥杯的考察重点:加黑重点 (括号内了解)

        算法:枚举、排序搜索、计数、贪心动态规划、图论、数论、博弈论、概率论、计算几何、字符串算法。(递归、二分查找、哈希算法、分治算法、回溯算法)

        数据结构:数组、对象/结构、字符串、队列、平衡树/线段树、复杂数据结构、嵌套数据结构。(链表、散列表、二叉树、跳表、Trie树)

编程思维: 说明
数学思维 公式计算
计算思维 程序自动化+抽象过程
计算机思维 不断试错
随机模拟思维 大量随机点模拟
模块化思维 功能拆分——化繁为简,分而治之,模块间松耦合,模块内紧耦合
规则化思维 抽象过程为规则
递归思维 函数内调用函数
脚本自动化思维 数据和功能分离

目录

算法复杂度

递归

fibonacci——爬楼梯 

数组

两数之和问题

合并两个有序数组

队列

二叉树

贪心算法

吃饼干问题

搜索 

DFS深度优先搜索(Depth First Search)

回溯法

BFS广度优先搜索(Broadth_First Search)

二叉树的遍历

前序遍历

中序遍历

后序遍历

层次遍历

动态规划(Dynamic Programming)

背包问题

最长公共子串问题

最长公共子序列问题(LCS)

排序

快速排序

归并排序

冒泡排序

选择排序

插入排序


算法复杂度

包括时间复杂度和空间复杂度。

对于程序需要优先考虑时间。Tn = O(f(n))。时间复杂度是对程序运行时间的估算。

图片

 计算:(超过2层循环的算法直接换思路,时间复杂度小于等于O(n**2))

        选择最复杂的循环计算最高阶(包括递归调用,不包括其他循环和非循环)。

        嵌套取乘积。O(N*N)

        多数据规模。O(M+N)

例:等比数列2**i实现。

i = 1
while i <= n:
    i = i*2

i依次为1,2,4,8,16...2**i,直到2**i不大于n时停止。

2**i == n。i == log2(n)。

所以Tn = O(log(n))

递归

思想:(将一个复杂的大问题拆分为小问题来解决)

        一个问题的解等价于拆分为子问题的解。

        子问题规模变小,但是子问题与原问题思路相同。

        存在终止条件(符合算法的有限性)

评价:

        优点:递归思想简单,容易理解思考;

        缺点:空间复杂度高,堆栈溢出分险,耗时比较高,重复计算问题。

fibonacci——爬楼梯 

斐波纳吉序列就是典型的递归思想。

1.  递归法解决问题,自顶向下计算,时间复杂度高。T(n) = O(n^{2})

#递归fibonacci

def fun(n):
    if n == 0:
        return 0
    elif n == 1:
        return 1
    else:
        return fun(n-1) + fun(n-2)

n = int(input())
num = fun(n)
print(num)

2.  递归中存在重复计算问题,将已经计算过的值保存到字典。T(n) = O(n)

#hashmap()存储已经计算的值

di = {}
def func(n):
    if n == 0:
        return 0
    elif n == 1:
        return 1
    else:
        if n in di:
            return di.get(n)
        else:
            result = func(n-1) + func(n-2)
            di[n] = result
            return result

n = int(input())
num = func(n)
print(num)

3. 递推方式,自底向上累加,难理解(用变量临时保存子问题的解)。T(n) = O(n)

#循环,自底向上

def fibonacci(n):
    a = 0
    b = 1
    if n == 0:
        return 0
    elif n == 1:
        return 1
    for i in range(1,n):
        c = a+b
        a = b
        b = c
    return b

n = int(input())
num = fibonacci(n)
print(num)

数组

两数之和问题

描述:找出一个一维数组(li)中,两个数和为目标值(n)的下标。

暴力枚举法。T(n) = O(n^{2})

li = [2,7,11,15]
n = 9
for i in range(len(li)):
    for j in range(i+1,len(li)):
        if li[j]+li[i] == n:#如果两个数之和等于目标值,返回下标
            print(i,j)

用字典存储遍历过的值。T(n) = O(n)

li = [2,7,11,15,13]
n = 20
di = {}#键存储数据,值存储下标
for i in range(len(li)):
    sub = n - li[i]
    if sub in di:#判断差值在字典中是否有键,有则返回下标;没有存入字典
        print(di[sub],i)
    else:
        di[li[i]] = i

合并两个有序数组

描述:将两个递增数组(a,b)合并,并且排序。结果存储在(a)。——一次归并排序

用列表方法——list.extend()合并,list.sort()排序。(只能说python的列表就是np。数组遍历真烦。。。)sort()快速排序的时间复杂度:T(n) = O((M+N)log(M+N))

a = [1,5,9]
b = [3,5,7]
a = a+b
a.sort()
print(a)

双指针遍历列表(利用列表有序),比较存入临时列表,再赋值给(a)。T(n) = O(M+N)S(n) = O(M+N)

双指针从后向前倒序遍历,先排序值大的元素,直接存入(a)。T(n) = O(M+N)

### 蓝桥杯 Python 算法题及解答 #### 题目一:最长滑雪道(记忆化搜索) 此题目涉及动态规划与记忆化搜索的概念。给定一个二维数组 `heights` 表示山的高度分布,求从任意一点出发能够滑到的最大长度路径。滑雪条件为当前高度大于下一位置高度。 以下是基于记忆化搜索的解决方案: ```python def longest_ski_path(heights): from functools import lru_cache rows, cols = len(heights), len(heights[0]) @lru_cache(None) def dfs(r, c): max_len = 1 directions = [(0, 1), (1, 0), (0, -1), (-1, 0)] for dr, dc in directions: nr, nc = r + dr, c + dc if 0 <= nr < rows and 0 <= nc < cols and heights[nr][nc] < heights[r][c]: max_len = max(max_len, 1 + dfs(nr, nc)) return max_len result = 0 for i in range(rows): for j in range(cols): result = max(result, dfs(i, j)) return result # 测试样例 heights = [ [9, 8, 7], [6, 5, 4], [3, 2, 1] ] print(longest_ski_path(heights)) # 输出应为 9 ``` 上述代码通过递归加缓存的方式实现记忆化搜索[^1]。 --- #### 题目二:最大矩形面积 该问题要求在一个由字符组成的矩阵中找到全为特定字符构成的最大矩形区域并返回其面积。例如,在一面墙上找一块空白区域用于涂鸦。 下面是解决方法之一: ```python def maximal_rectangle(matrix): if not matrix or not matrix[0]: return 0 m, n = len(matrix), len(matrix[0]) height = [0] * (n + 1) # 多余的一位是为了处理栈中的边界情况 max_area = 0 for row in matrix: for i in range(n): height[i] = height[i] + 1 if row[i] == '1' else 0 stack = [-1] for i in range(n + 1): # 将最后一位作为哨兵触发计算 while height[i] < height[stack[-1]]: h = height[stack.pop()] w = i - stack[-1] - 1 max_area = max(max_area, h * w) stack.append(i) return max_area # 测试样例 matrix = [ ["1", "0", "1", "0", "0"], ["1", "0", "1", "1", "1"], ["1", "1", "1", "1", "1"], ["1", "0", "0", "1", "0"] ] print(maximal_rectangle(matrix)) # 输出应为 6 ``` 这段代码利用单调栈的思想来高效解决问题[^2]。 --- #### 题目三:最小公倍数最大化 已知正整数 $ N $ ,从中选取三个不同的数使得它们的最小公倍数尽可能大。分析发现最优策略是从连续的几个较大数值中挑选组合。 提供如下实现方案: ```python def largest_lcm(N): if N % 2 == 1: return N * (N - 1) * (N - 2) elif N % 3 != 0: return N * (N - 1) * (N - 3) else: return (N - 1) * (N - 2) * (N - 3) # 测试样例 print(largest_lcm(9)) # 输出应为 504 ``` 这里采用了分情况讨论的方法得出结论[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值