题目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))