左神中级提升班2(Python)

题目1:给定一个非负整数n,代表二叉树的节点个数。返回能形成多少种不同的二叉树结构。

解题思路:

方法1:递归

当N为0时,空树一种;N为1时,一种;N为二时,左子树右子树各一个为一种,共俩种。

 当节点个数为N时,左数为i个节点,右数则为N-i-1个节点,即F(i)和F(N-i-1),结果则为F(i)*F(N-i-1)。

def num5(N):
    if N < 2: return 1
    if N == 2: return 2
    res = 0
    for i in range(N):
        leftway = num5(i)
        rightway = num5(N-i-1)
        res += leftway * rightway
    return res
N = 3
print('num5:',num5(N))

 方法2:动态规划

def num5dp(N):
    if N<2: return 1
    dp = [0]*(N+1)
    dp[0] = 1
    # 枚举节点个数
    for i in range(1, N+1):
        # 枚举左子树的节点个数
        for j in range(i):
            # 左子树为j,右子树则为i-j-1
            dp[i] += dp[j]*dp[i-j-1]
    return dp[N]

题目2:

def num6(str):
    count, ans = 0, 0
    # count:左括号多出的数,需要添加右括号的数
    # ans:右括号多出的数,需要添加左括号的数
    for i in range(len(str)):
        if str[i] == '(':
            count+=1
        else:
            # 当遇到右括号时,左边没有左括号与他匹配
            if count == 0:
                ans+=1
            # 有与他匹配
            else:
                count-=1
    return count + ans

题目3:给定一个数字arr,求差值为k的去重数字对。

from collections import defaultdict
def num7(arr,k):
    # 讲arr从大到小排序
    arr = sorted(arr, reverse=True)
    dic = defaultdict(list)
    for i in range(len(arr)):
        for j in range(i+1, len(arr)):
            # 例如7-5刚好等于k 2,则将其添加入字典
            if arr[i]-arr[j] == k and arr[i] not in dic:
                dic[arr[i]].append(arr[j])
    return dic

题目4:

解题思路:1.如果两个集合的平均值相等,无法做magic操作;

                  2.俩个集合平均值不一样,只能从平均值大的集合拿到平均值小的集合,大家的平均值才都会增加,且拿的数x要满足(avg大<x<avg小),且要从满足要求内的这些数中挑最小的,才会使得能进行更多得magic操作。

# 保证arr1无重复值,arr2无重复值,且arr1和arr2肯定有数字
def num8(arr1, arr2):
    sum1 = sum(arr1)
    sum2 = sum(arr2)
    # 平均值相同,返回0
    if sum1/len(arr1) == sum2/len(arr2): return 0
    #平均值不相同
    if sum1/len(arr1) > sum2/len(arr2):
        arrMore = arr1
        sumMore = sum1
        arrLess = arr2
        sumLess = sum2
    else:
        arrMore = arr2
        sumMore = sum2
        arrLess = arr1
        sumLess = sum1
    arrMore.sort()
    moreSize = len(arrMore)  # 平均值大的集合还剩几个数
    lessSize = len(arrLess)  # 平均值小的集合还剩几个数字
    opt = 0  # 操作了几次
    for i in range(len(arrMore)):
        if arrMore[i] < sumMore/moreSize and arrMore[i] > sumLess/lessSize and arrMore[i] not in arrLess:
            sumMore -= arrMore[i]
            sumLess += arrMore[i]
            moreSize -= 1
            lessSize += 1
            arrLess.append(arrMore[i])
            opt += 1
    return opt

a = [10,12,14,8]
b = [1,6,4,2]
print(num8(a, b))

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值