阿里的两道算法笔试题(算法实习生)
1、切分为3的倍数的最多的个数
解法:递归(深度优先遍历)
# 递归,深度优先遍历
# 问题:切分为3的倍数的最多的个数
s = '23011112333132'
n = len(s)
ans = 0
def recur(res, s, first, last):
if last > len(s): return res
# 如果此时为3的倍数,结果加1,且让first直接跳转到last,即first=last,last=last+1
# 如果不为3的倍数,则我们继续往后看,即last=last+1
if int(s[first: last])%3 == 0:
res += 1
res = recur(res, s, last, last+1)
else:
res = recur(res, s, first, last+1)
return res
# 从第i个数开始递归,求得以i开头切分为3的倍数的个数
# 更新其中的最大值
for i in range(n):
res = recur(0, s, i, i+1)
ans = max(ans, res)
print(ans)
2、把a变为b所需的转换次数,a由0和1组成,当a和b不同时转换次数为1;但a中的i位置和j位置可以调换位置,转换次数为|j-i|
解法:动态规划
# 问题:把a变为b所需的转换次数,a由0和1组成,当a和b不同时转换次数为1;
# 但a中的i位置和j位置可以调换位置,转换次数为|j-i|
# 动态规划
a, b = '11110101', '10001010'
n = len(a)
dp = [0 for _ in range(n)]
dp[0] = 0 if a[0] == b[0] else 1
# 计算前i步的转换次数
for i in range(1, n):
# 如果a[i]和b[i]相等,dp[i]=dp[i-1];
# 如果a[i]和b[i]不相等,继续判断a[i-1]和b[i-1]是否相等,如果相等,dp[i]=dp[i-1]+1;
# 如果不相等,继续判断a[i-1]和a[i]是否相等,如果相等,dp[i]=dp[i-1]+1;
# 如果不相等,继续判断上一个dp和上上一个dp是否相等,即判断dp[i-1]是否等于dp[i-2],
# 如果相等,则dp[i]=dp[i-1]+1;如果不相等,则dp[i]=dp[i-1]
if a[i] != b[i]:
if a[i-1] != b[i-1]:
if a[i] != a[i-1]:
if i >= 2:
if dp[i-1] == dp[i-2]:
dp[i] = dp[i-1] + 1
continue
dp[i] = dp[i-1]
else:
dp[i] = dp[i-1] + 1
else:
dp[i] = dp[i-1] + 1
else: dp[i] = dp[i-1]
print(dp[-1])