左神中级班题目1

文章讨论了解决两个编程问题:使用滑动窗口方法计算绳子覆盖数组中点的数量,以及利用捆绑交易策略最小化购买苹果所需的袋子数量。还涉及到了预处理数组优化算法效率的方法。
摘要由CSDN通过智能技术生成

题目1:给定一个有序数组arr,代表数轴上从左到右有n个点arr[0],arr[1]...arr[n-1],给定一个正数L,代表一根长度为L的绳子,求绳子最多能覆盖其中的几个点。

解题思路:使用滑动窗口的方法,通过维护一个窗口,使得窗口内覆盖的值最大,当下一个参数减去窗口的最左边的值小于绳子的长度L,则窗口的最右边往右滑一步,否则窗口的最左边往右滑。

def num1(arr,L):
    N = len(arr)
    left, right = 0, 0
    m = 0
    while left < N :
        while right < N and arr[right]-arr[left]<=L:
            right+=1
        m = max(m, right-left)
        left+=1
    return m
arr = [2,4,8,9,12,17]
L = 5
k = num1(arr,L)

题目2:小虎去附近的商店买苹果,奸诈的商贩使用了捆绑交易,只提供6个每袋和8个每袋的包装包装不可拆分。可是小虎现在只想购买恰好n个苹果,小虎想购买尽量少的袋数方便携带。如果不能购买恰好n个苹果,小虎将不会购买。输入一个整数n,表示小虎想购买的个苹果,返回最小使用多少袋子。如果无论如何都不能正好装下,返回-1。
解题思路:先尽量使用8类型的袋子,看剩下的苹果能不能被6类型的袋子装完,不行就8类型的袋子减一,继续看剩下的苹果能不能被6类型的袋子装完,试完都不行的话返回-1,N为奇数的话也不行。当我剩余的苹果数一旦超过24以上,下面的都不成立,剩余的24个苹果要用6类型的袋子搞定,而8类型也可以搞定这24个苹果。24是6和8的最小公倍数。

def num2(apple):
    if apple<0:
        return -1
    bag6 = -1
    bag8 = apple//8
    rest = apple-bag8*8
    while (bag8>=0 and rest < 24):
        restuse6 = rest/6 if rest % 6==0 else -1
        if restuse6 != -1:
            bag6 = restuse6
            break
        bag8-=1
        rest = apple - bag8*8
    return -1 if bag6==-1 else bag8+bag6
print(num2(14))

方法2:打表法,当题目输入参数为整数,输出结果也为整数,观察输出的结果,通过数学规律写出代码,即为最优解。

def num22(apple):
    # 奇数返回-1
    if apple % 2!=0: return -1
    if apple<18:
        if apple ==0: return 0
        elif apple==6 or apple==8: return 1
        elif apple==12 or apple==14 or apple==16: return 2
        else: return -1
    return (apple - 18) / (8+3)
print(num22(14))

题目3:

解题思路:

for循环每一步都进行枚举,时间复杂度太高;可以创建数组AB,分别记录0-i有多少个R和i-N-1有多少个G,计算的时候直接拿即可。

知识点:预处理数组,用空间换时间。

def num3(color):
    color = list(color)
    N = len(color)
    A = [0]*N # 记录0 - i有多少个G
    B = [0]*N # 记录i - N-1有多少个R
    N = len(color)
    for i in range(N-1, -1, -1):
        if color[i] == 'R':
            B[i] = 1 if i == N-1 else B[i+1] + 1
        else:
            B[i] = 0 if i == N-1 else B[i+1]
    # 赋值B[0],全部染成G的情况
    res = B[0]
    for i in range(N):
        if color[i] == 'G':
            A[i] = 1 if i == 0 else A[i-1] + 1
        else:
            A[i] = 0 if i == 0 else A[i-1]
        # 记录最小值,i==N-1时,全部染成G的情况
        res = min(res, A[i]) if i == N-1 else min(res, A[i] + B[i+1])
    return res
str = 'RRRRR'
print(num3(str))

题目4:

解题思路:

      1.从下往上,从右往左建立right矩阵,计该点右边有多少个连续的1;从下往上建立down矩阵,计算该点从下往上有多少个连续的1。创建预处理数组,省去了在里面建立四个for循环判断是都为1的时间。

       2.当确认左上方顶点时,可以通过矩阵查询右上角点,左下角点是否都符合条件。

def num4(arr):
    N = len(arr)  # 行
    M = len(arr[0])  # 列
    if N < 1: return 0
    right = np.zeros((N, M))
    down = np.zeros((N, M))
    # 创建right数组
    for row in range(N):
        for col in range(M-1, -1, -1):
            if arr[row][col] == 1:
                right[row][col] = 1 if col == M-1 else right[row][col+1] + 1
            else:
                right[row][col] = 0
    # 创建down数组
    for col in range(M):
        for row in range(N-1, -1, -1):
            if arr[row][col] == 1:
                down[row][col] = 1 if row == N - 1 else down[row+1][col] + 1
            else:
                down[row][col] = 0
    res = 0
    for row in range(N):
        for col in range(M):
            maxBorder = min(N - row, M - col)
            for border in range(1, maxBorder+1):
                if right[row][col] >= border and down[row][col] >= border and down[row][int(col+border-1)] >= border and right[int(row+border-1)][col]>=border:
                    res = max(res, border)
    return res

arr = [[1,0,1,1,1],[1,0,1,0,1],[1,1,1,1,1],[1,0,1,0,0]]
print('border',num4(arr))

题目5:

解题思路:

1.首先利用f函数生成等概率返回0、1的函数,例如在1-5中,f返回1、2返回0,f返回3、4返回1,f返回5重新进入f。

2.再确定1-7需要7个数字,至少要3位二进制数字,构造返回值位0-6的函数,利用01函数生成三位二进制数,当其大于6时候重新生成。

3.该函数生成01或者10的概率都为p*(1-p),因此生成数字位01返回0,生成数字位10返回1,生成数字位00或11重新生成。

  • 22
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值