废物刷算法(python)

目录

递归(DFS)

1.Hanoi问题

2.全排列(DFS)

排序

1.冒泡排序

2.选择排序 

3.插入排序

4.快速排序

链表

哈希表

贪心算法

DP

1.切钢管问题——一维DP

2.01背包问题——二维DP

 3.分割两个子集——二维DP


递归(DFS)

1.Hanoi问题

这个问题起源于一个类似传说故事,在Hanoi这个地方有一个寺庙,这里有3根柱子和64个大小不同的金碟子。每个碟子有一个孔可以穿过。所有的碟子都放在第一个柱子上,而且按照从上到下碟子的大小依次增大的顺序摆设。如下图:

    现在,假定寺庙里的僧侣要移动这些碟子,将它们从最左边移动到最右边的柱子上。不过移动的规则如下:

1. 每次只能从一个柱子的最上面移动一个碟子到另外一个柱子上。

2. 不能将大碟子放到小碟子的上面。

    按照前面这个规则,我们该怎么去移动这些碟子呢?假定单位时间内可以移动一片碟子,那么最终移动这些碟子到目的柱子需要多长的时间呢?

def hanoi(n,a,b,c):
    if n>0:
        hanoi(n-1,a,c,b)
        print('moving from %s to %s'%(a,c))
        hanoi(n-1,b,a,c)
hanoi(3,'A','B','C')

2.全排列(DFS)

n=int(input())
vis=[0]*(n+1)
num=[0]*(n+1)
def dfs(step):
    if step==n+1:
        for i in num[1:]:
            print(i,end=' ')
        print()
        return
    for i in range(1,n+1):
        if vis[i]==0:
            num[step]=i
            vis[i]=1
            dfs(step+1)
            vis[i]=0
    return
dfs(1)

查找

1.二分查找

class Solution:
    def search(self, nums: list[int], target: int) -> int:
        left = 0
        right = len(nums) - 1
        while left <= right:
            mid = (left + right) // 2
            if nums[mid] == target:
                return mid
            elif nums[mid] > target:
                right = mid - 1
            else:
                left = mid + 1
        else:
            return -1

排序

1.冒泡排序

import random
def randlist(n):
    a=list()
    for i in range(n):
        a.append(random.randrange(0,1000,1))
    return a

def Bubble_sort(list):
    for i in range(len(list)-1):
        for j in range(len(list)-1):
            if list[j]>list[j+1]:
                list[j],list[j+1]=list[j+1],list[j]
    return list

list1=randlist(20)
print(list1)
list1=Bubble_sort(list1)
print(list1)

2.选择排序 

import random


def list_create(n):
    a = list()
    for i in range(n):
        a.append(random.randint(0, 15))
    print(a)
    return a


def Select_Sort_1(list):
    b = []
    for i in range(len(list)):
        min_num = min(list)
        b.append(min_num)
        list.remove(min_num)
        print(b)
    return b


def Select_Sort_2(li):
    for i in range(len(li)):
        max_num = 0
        location = 0
        for j in range(len(li) - i):
            if li[j] > max_num:
                max_num = li[j]
                location = j
        li[location], li[len(li) - i - 1] = li[len(li) - i - 1], li[location]
        print(li)
    return li


m = [1, 5, 3, 9, 6, 4, 7, 7, 2, 3, 5, 4]
n = [1, 5, 3, 9, 6, 4, 7, 7, 2, 3, 5, 4]
Select_Sort_1(m)
print(' * ' * 20)
Select_Sort_2(n)

3.插入排序

4.快速排序

import random


def list_create(n):
    a = list()
    for i in range(n):
        a.append(random.randint(0, 100))
    print(a)
    return a


def partition(li, left, right):
    tmp = li[left]
    while left < right:
        while tmp < li[right] and left < right:
            right -= 1
        if left >= right:
            break
        li[left] = li[right]
        left += 1
        if left >= right:
            break
        while tmp > li[left] and left < right:
            left += 1
        if left >= right:
            break
        li[right] = li[left]
        right -= 1
    li[left] = tmp
    print(m)
    return left


def quick_sort(li, left, right):
    if left < right:
        mid = partition(li, left, right)
        quick_sort(li, left, mid - 1)
        quick_sort(li, mid + 1, right)

    return li


m = list_create(10)
print(m)
quick_sort(m, 0, len(m) - 1)
print(m)

链表

import random
#用一个类表示列表的一个节点
class Node:
    def __init__(self,val):
        self.val=val
        self.next=None

#创建链表_头插法
def creat_linklist_head(list):
    head = Node(list[0])
    for i in list[1:]:
        node=Node(i)
        node.next=head
        head=node
    return head
#创建链表_尾插法
def creat_linklist_tail(list):
    head = Node(list[0])
    tail=head
    for i in list[1:]:
        node=Node(i)
        tail.next=node
        tail=node
    return head
#链表打印
def linklist_print(head):
    m=head
    while m:
        print(m.val,end=', ')
        m=m.next

a=[1,3,5,9,7,8]
print(a)
b=creat_linklist_head(a)
c=creat_linklist_tail(a)
linklist_print(b)
print()
linklist_print(c)

哈希表

贪心算法

找零问题,有面值 100 50 20 5 1的RMB,怎么找零使得钱的数量最少
t=[100,50,20,5,1]
def greedy(money):
    pieces=[0 for i in range(len(t))]
    for i,temp in enumerate(t):
        pieces[i]=money//t[i]
        money%=t[i]
    return pieces
print(greedy(7))

DP

1.切钢管问题——一维DP

#钢管切割问题
p=[0,1,5,8,9,10,17,17,20,24,30]
def Solution(p,n):
    if n==0:
        return p[n]
    else:
        waste_max=p[n]
        for i in range(1,n):
            waste_max=max(waste_max,Solution(p,i)+Solution(p,n-i))
        return waste_max
print(Solution(p,9))
#使用递归算法加动态规划

2.01背包问题——二维DP

        给你一个可装在W的背包和N个物品,每个物品的有重量和价值两个属性,第i个物品的重量是wt[i],价值为val[i],现在让你用这个背包装物品,最多能装的价值是多少?

def backage(N,W,wt,val):
    dp = []
    for i in range(N + 1):
        dp.append([0] * (W + 1))
    for i in dp:
        print(i)
    for i in range(N+1):
        for w in range(W+1):
            if i==0 or w==0:
                dp[i][w]=0
            elif w-wt[i]<0 :
                dp[i][w]=dp[i-1][w]
            else:
                dp[i][w]=max(dp[i-1][w],dp[i-1][w-wt[i]]+val[i])
    print(dp[i][w])


#N,W=map(int,input().split())
N,W=3,4
wt=[0,2,1,3]
val=[0,4,2,4]
backage(N,W,wt,val)
#dp[i][w]的含义为:选择前i个物品装入重量为w的背包中,所能创造的最大价值

 3.分割两个子集——二维DP

给你一个 只包含正整数 的 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。

示例 1:

输入:nums = [1,5,11,5]
输出:true
解释:数组可以分割成 [1, 5, 5] 和 [11] 。

示例 2:

输入:nums = [1,2,3,5]
输出:false
解释:数组不能分割成两个元素和相等的子集。
def Solution(num):
    plus = sum(num)
    if plus % 2 != 0:
        return False
    else:
        W = int(plus / 2)
        N = len(num)
        val = [0]
        val.extend(num)
        wt = [0]
        wt.extend(num)
        dp = []
        for i in range(len(num) + 1):
            dp.append([0] * (W + 1))
        for i in range(N+1):
            for w in range(W+1):
                if i ==0 or w==0:
                    dp[i][w]=0
                elif w-wt[i]<0 :
                    dp[i][w]=dp[i-1][w]
                else:
                    dp[i][w]=max(dp[i-1][w],dp[i-1][w-wt[i]]+val[i])
        if dp[i][w]==W:
            print('可以分割成两个相等的子序列和,每个子序列的和为%d'%W)
        else:
            print('不可以分割成两个相等的子序列和')

nums = [1,11, 2, 2, 6, 4]
Solution(nums)

  • 12
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值