python算法综合(不断更新)

本文深入探讨了算法题的解决策略,包括生成螺旋矩阵、递归问题解析、动态规划应用及贪心算法实例,旨在提升算法理解和实践能力。

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

今后努力还是要刷算法题

一、 生成螺旋矩阵copy个6阶的螺旋矩阵过来~

[[ 1.  2.  3.  4.  5.  6.]
 [20. 21. 22. 23. 24.  7.]
 [19. 32. 33. 34. 25.  8.]
 [18. 31. 36. 35. 26.  9.]
 [17. 30. 29. 28. 27. 10.]
 [16. 15. 14. 13. 12. 11.]]

找到一个很好的答案:https://www.cnblogs.com/pyonwu/p/12215086.html

思路:
1.先生成一个零矩阵,再往里面填充数字;
2.每填充完一个,都判断下一步该往哪走,下一步有四种状态:横+、纵+、横-、纵-,依次循环。
3.每种状态间切换的条件:原状态的下一步的元素已被填充(!=0)或索引溢出。
import numpy as np
def r_matrix(n):
    mt = np.zeros(n**2).reshape(n,n)
    x, y = 0, 0
    num = 1
    direction = 1

    while mt[x][y] == 0:
        mt[x][y] = num
        num += 1
        if -1<y+direction<n  and mt[x][y+direction] == 0:
            y += direction
        elif x+direction<n and mt[x+direction][y] == 0:
            x += direction
        else:
            direction = -direction
            y += direction
    return mt

 

二、递归问题:https://mp.weixin.qq.com/s/mJ_jZZoak7uhItNgnfmZvQ

1. 一个人赶着鸭子去每个村庄卖,每经过一个村子卖去所赶鸭子的一半又一只。这样他经过了七个村子后还剩两只鸭子,问他出发时共赶多少只鸭子?

import numpy as np
def sunn(n,m,p):
      if n == m:
           # sunn(7,7) == 2
            return p
            
      return (sunn(n+1,m)+1)*2

if __name__ =='__main__':
      print(sunn(0,7,p))

2. n级台阶的楼梯,从下往上走,每跨一步只能向上1级或者2级台阶,共有多少种走法。

f(0)=0;f(1)=1;f(n)=f(n-1)+f(n-2)

递归过程之所以耗时,是因为每一次递归都需要在栈中开辟新的调用栈执行子方法,在栈的反复开辟、销毁过程中,不仅耗时激增,最为关键的是,反复的栈开辟让内存占用率急剧增长。

递归实现:缺点容易爆栈
def jumpFloor(number):
    if number == 0:
        return 0
    if number == 1:
        return 1
    if number == 2:
        return 2
    return jumpFloor(number - 1) + jumpFloor(number - 2)

 

尾递归的方式,基本思路是通过一个参数来保存上次执行结果,另一个参数保存累计值
import time


def jumpFloor(number):
    if number == 0:
        return 0
    if number == 1:
        return 1
    if number == 2:
        return 2
    return solute(number, 0, 1)


def solute(number, a, b):
    if number == 0:
        return b
    return solute(number-1, b, a+b)


if __name__ == '__main__':
    starttime = time.time()
    print(jumpFloor(400))
    print('耗时:' + str(time.time() - starttime))
#备忘录实现
def Floor_Memo(number):
    memo = {1: 1, 2: 2}  # 边界条件
    count = 2
    while count < number:
        count += 1
        memo[count] = memo[count - 1] + memo[count - 2]  # 状态转移方程
    return memo[number]

 

# 动态规划实现:以空间复杂度换时间复杂度,只记F(N-1)和F(N-2)
def Floor_DP(number):
    if number == 1:  # 边界条件
        return 1
    if number == 2:  # 边界条件
        return 2
    result = [1, 2]  # 只存储前2次结果
    count = 2
    while count < number:
        nexta = sum(result)
        result = [result[1], nexta]  # 等同于状态转移方程
        count += 1
    return result[-1]
# 循环
def fibs(n):
    a = [1, 1]
    for i in range(n - 2):
        a.append(a[-2] + a[-1])
    return a[n-1]

print(fibs(6))

 

参考:

https://techlog.cn/article/list/10183325

https://www.jianshu.com/p/ced3f00e880e?utm_medium=timeline&utm_source=oschina-app

 

3.一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。

因为n级台阶,第一步有n种跳法:跳1级、跳2级、到跳n级

跳1级,剩下n-1级,则剩下跳法是f(n-1)
跳2级,剩下n-2级,则剩下跳法是f(n-2)
所以f(n)=f(n-1)+f(n-2)+…+f(1)
因为f(n-1)=f(n-2)+f(n-3)+…+f(1)
所以f(n)=2*f(n-1)

在这里插入图片描述

 4.我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?

同 题2

 

三、 动态规划:https://www.cnblogs.com/kubidemanong/p/11854724.html

1.0-1背包问题

假设我们有n件物品,分别编号为1, 2…n。其中编号为i的物品价值为vi,它的重量为wi。为了简化问题,假定价值和重量都是整数值。现在,假设我们有一个背包,它能够承载的重量是W。现在,我们希望往包里装这些物品,使得包里装的物品价值最大化,那么我们该如何来选择装的东西

 

定义一个函数c[i, w]表示到第i个元素为止,在限制总重量为w的情况下我们所能选择到的最优解。

在这里插入图片描述

 

import numpy as np

def solve(vlist,wlist,totalWeight,totalLength):
    resArr = np.zeros((totalLength+1,totalWeight+1),dtype=np.int32)
    for i in range(1,totalLength+1):
        for j in range(1,totalWeight+1):
            if wlist[i] <= j:
                resArr[i,j] = max(resArr[i-1,j-wlist[i]]+vlist[i],resArr[i-1,j])
            else:
                resArr[i,j] = resArr[i-1,j]
    return resArr[-1,-1]

if __name__ == '__main__':
    v = [0,60,100,120]
    w = [0,10,20,30]
    weight = 50
    n = 3
    result = solve(v,w,weight,n)
    print(result)

参考:https://blog.csdn.net/ningngmei4328/article/details/91356784

2. 最长上升子序列

https://leetcode-cn.com/problems/longest-increasing-subsequence/solution/zui-chang-shang-sheng-zi-xu-lie-dong-tai-gui-hua-2/

给定一个无序的整数数组,找到其中最长上升子序列的长度。

示例:

输入: [10,9,2,5,3,7,101,18]
输出: 4
解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4。

 时间复杂度应该为 O(n2)

class Solution:
    def lengthOfLIS(self, nums):
        if not nums: 
            return 0
        
        n, res = len(nums), 1    # 序列长度和初始化最长上升子序列长度
        dp = [1]*n               # 初始化 dp
        for i in range(1, n):
            for j in range(i):
                if nums[i] > nums[j]:
                    dp[i] = max(dp[i], dp[j]+1)    # 更新 dp
            res = max(res, dp[i])                  # 更新最长上升子序列长度
        return res


test = Solution()
nums = [10,9,2,5,3,7,101,18]
test.lengthOfLIS(nums)

二分法求解时间复杂度降低到 O(n log n)

class Solution:
    def lengthOfLIS(self, nums):
        if not nums:
            return 0
        
        top = []                           # 整体数组
        for i in range(len(nums)):
            # 二分查找插入数组
            left, right = 0, len(top)-1    # 左右边界索引
            while left <= right:          
                mid = (left+right)//2      # 左中位数
                if top[mid][-1] < nums[i]:
                    left = mid+1
                else:
                    right = mid-1
            # 若 left 等于数组的个数,则需要添加新数组;否则,在 left 数组尾部添加新值
            if left == len(top):
                top.append([nums[i]])
            else:
                top[left].append(nums[i])
        return len(top)

参考:https://blog.csdn.net/qq_36512295/article/details/100835261

 

 

四、贪心算法:https://blog.csdn.net/sweetseven_/article/details/95197131

1. 已知一些孩子和一些糖果,每个孩子有需求因子g,每个糖果有大小s,当某个糖果的大小s>=某个孩子的需求因子g时,代表该糖果可以满足该孩子,求使用这些糖果,最多能满足多少孩子(注意,某个孩子最多只能用1个糖果满足)

虽说贪心算法并不一定能达到最优,但在这种情况感觉如下这样算应该使最优解?????

class Solution:
    def findContentChild(self,g,s):
        g = sorted(g)
        s = sorted(s)
        child = 0
        cookie = 0
        while child < len(g) and cookie < len(s):
            if g[child] <= s[cookie]:
                child +=1
            cookie+=1
        return child
if __name__ =="__main__":
    g = [5,10,2,9,15,9]
    s = [6,1,20,3,8]
    S = Solution()
    result = S.findContentChild(g,s)
    print(result)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值