目录
报名链接:点击进入青训营报名
https://juejin.cn/activityregister/7437097112547901484/info?utm_source=practice&utm_medium=youthcamp&utm_campaign=campus_2030175862391756
入营打卡链接:点击进入青训营入营考核题库
https://juejin.cn/problemset?utm_source=practice&utm_medium=youthcamp&utm_campaign=youthcamp-examine
题目(序号对应题目序号):
1、找单独的数
def solution(inp):
# Edit your code here
num_dict = {}
for num in inp:
if num in num_dict:
num_dict[num] += 1
else:
num_dict[num] = 1
for num, count in num_dict.items():
if count == 1:
return num
return 0
if __name__ == "__main__":
# Add your test cases here
print(solution([1, 1, 2, 2, 3, 3, 4, 5, 5]) == 4)
print(solution([0, 1, 0, 1, 2]) == 2)
2、徒步旅行中的补给问题
def solution(n, k, data):
dp = [[float('inf')] * (k + 1) for _ in range(n + 1)]
dp[0][0] = 0
for i in range(1, n + 1):
for l in range(k):
for j in range(k):
if l - j + 1 >= 0 and l - j + 1 <= k:
dp[i][l] = min(dp[i][l], dp[i - 1][j] + (l - j + 1) * data[i - 1])
# print(dp)
return dp[n][0]
if __name__ == "__main__":
print(solution(5, 2, [1, 2, 3, 3, 2]) == 9)
print(solution(6, 3, [4, 1, 5, 2, 1, 3]) == 9)
print(solution(4, 1, [3, 2, 4, 1]) == 10)
3、徒步旅行中的补给问题
def solution(s: str) -> str:
# write code here
index = -1
for i in range(len(s)):
if s[i] == '.':
index = i
cnt = 0
sz = ""
sx = ""
if index >= 0:
sz = s[0:index]
sx = s[index:len(s)]
else:
sz = s
for x in range(len(sz)):
if s[x] == '0':
cnt = cnt + 1
else:
break
sz = s[cnt:len(sz)]
a = len(sz) % 3
new_s = ""
for i in range(len(sz)):
if a == 0 & i != (len(sz) - 1):
if i != 0:
new_s = new_s + "," + sz[i]
else:
new_s = new_s + sz[i]
a = 2
else:
new_s = new_s + sz[i]
a = a - 1
new_s = new_s + sx
return new_s
if __name__ == '__main__':
print(solution("1294512.12412") == '1,294,512.12412')
print(solution("0000123456789.99") == '123,456,789.99')
print(solution("987654321") == '987,654,321')
4、数字分组求偶数和
def is_even(num):
"""Check if a number is even."""
return num % 2 == 0
def solution(numbers):
# 记录偶数和奇数的个数
count_even = 1 # 可能选择的偶数数量 (初始化为 1)
count_odd = 0 # 可能选择的奇数数量 (初始化为 0)
for group in numbers:
evens = sum(1 for char in str(group) if is_even(int(char)))
odds = len(str(group)) - evens # 奇数数量
# 计算新的偶数和奇数组合数
new_count_even = count_even * evens + count_odd * odds
new_count_odd = count_even * odds + count_odd * evens
# 更新当前的偶数和奇数组合数
count_even = new_count_even
count_odd = new_count_odd
# 最终的结果是所有选择方案中,和为偶数的方案数量
return count_even
if __name__ == "__main__":
# You can add more test cases here
print(solution([123, 456, 789]) == 14)
print(solution([123456789]) == 4)
print(solution([14329, 7568]) == 10)
7、创意标题匹配问题
def match_template(template, title):
if not template and not title:
return True
if not template:
return all(c == '{' or c == '}' for c in title)
if not title:
return all(c == '{' or c == '}' for c in template)
if template[0] == '{':
end = template.index('}')
for i in range(len(title) + 1):
if match_template(template[end + 1:], title[i:]):
return True
return False
if template[0] != title[0]:
return False
return match_template(template[1:], title[1:])
def solution(n, template, titles):
results = []
for title in titles:
results.append("True" if match_template(template, title) else "False")
return ",".join(results)
if __name__ == "__main__":
# You can add more test cases here
testTitles1 = ["adcdcefdfeffe", "adcdcefdfeff", "dcdcefdfeffe", "adcdcfe"]
testTitles2 = ["CLSomGhcQNvFuzENTAMLCqxBdj", "CLSomNvFuXTASzENTAMLCqxBdj", "CLSomFuXTASzExBdj", "CLSoQNvFuMLCqxBdj", "SovFuXTASzENTAMLCq", "mGhcQNvFuXTASzENTAMLCqx"]
testTitles3 = ["abcdefg", "abefg", "efg"]
print(solution(4, "ad{xyz}cdc{y}f{x}e", testTitles1) == "True,False,False,True" )
print(solution(6, "{xxx}h{cQ}N{vF}u{XTA}S{NTA}MLCq{yyy}", testTitles2) == "False,False,False,False,False,True" )
print(solution(3, "a{bdc}efg", testTitles3) == "True,True,False" )
8、找出整型数组中占比超过一半的数
def solution(array):
candidate = None
count = 0
for num in array:
if count == 0:
candidate = num
if num == candidate:
count += 1
else:
count -= 1
return candidate
if __name__ == "__main__":
# Add your test cases here
print(solution([1, 3, 8, 2, 3, 1, 3, 3, 3]) == 3)
16、最大矩形面积问题
def solution(n, array):
stack = []
max_area = 0
index = 0
while index < n:
# If this bar is higher than the bar at stack top, push it to the stack
if not stack or array[index] >= array[stack[-1]]:
stack.append(index)
index += 1
else:
# Pop the top
top_of_stack = stack.pop()
# Calculate the area with array[top_of_stack] as the smallest (or minimum height) bar
area = (array[top_of_stack] *
((index - stack[-1] - 1) if stack else index))
# Update max area, if needed
max_area = max(max_area, area)
# Now pop the remaining bars from stack and calculate area
while stack:
top_of_stack = stack.pop()
area = (array[top_of_stack] *
((index - stack[-1] - 1) if stack else index))
max_area = max(max_area, area)
return max_area
if __name__ == "__main__":
# Add your test cases here
print(solution(5, [1, 2, 3, 4, 5]) == 9)
25、DNA序列编辑距离
def solution(dna1, dna2):
m = len(dna1)
n = len(dna2)
# 创建一个(m+1) x (n+1)的二维列表来保存编辑距离
dp = [[0] * (n + 1) for _ in range(m + 1)]
# 初始化第一行和第一列
for i in range(m + 1):
dp[i][0] = i # 从dna1到空字符串的操作数为i(删除操作)
for j in range(n + 1):
dp[0][j] = j # 从空字符串到dna2的操作数为j(插入操作)
# 填充DP表
for i in range(1, m + 1):
for j in range(1, n + 1):
if dna1[i - 1] == dna2[j - 1]:
dp[i][j] = dp[i - 1][j - 1] # 字符匹配,无需操作
else:
dp[i][j] = min(dp[i - 1][j] + 1, # 删除操作
dp[i][j - 1] + 1, # 插入操作
dp[i - 1][j - 1] + 1) # 替换操作
return dp[m][n] # 返回最终的编辑距离
if __name__ == "__main__":
# You can add more test cases here
print(solution("AGCTTAGC", "AGCTAGCT") == 2 )
print(solution("AGCCGAGC", "GCTAGCT") == 4)
26、小U的数字插入问题
def solution(a: int, b: int) -> int:
# write code here
a_str = str(a)
max_num = 0
for i in range(len(a_str) + 1):
new_num_str = a_str[:i] + str(b) + a_str[i:]
new_num = int(new_num_str)
if new_num > max_num:
max_num = new_num
return max_num
if __name__ == '__main__':
print(solution(76543, 4) == 765443)
print(solution(1, 0) == 10)
print(solution(44, 5) == 544)
print(solution(666, 6) == 6666)
29、小D的 `abc` 变换问题
def solution(s: str, k: int) -> str:
# write code here
transformation_dict = {'a': 'bc', 'b': 'ca', 'c': 'ab'}
for _ in range(k):
new_s = ""
for char in s:
new_s += transformation_dict[char]
s = new_s
return s
if __name__ == '__main__':
print(solution("abc", 2) == 'caababbcbcca')
print(solution("abca", 3) == 'abbcbccabccacaabcaababbcabbcbcca')
print(solution("cba", 1) == 'abcabc')
41、最小替换子串长度
def solution(input):
n = len(input)
target = n // 4 # 目标频次
# 统计频次
freq = {'A': 0, 'S': 0, 'D': 0, 'F': 0}
for c in input:
freq[c] += 1
# 已经平衡
if all(f == target for f in freq.values()):
return 0
# 尝试每个可能的长度
for length in range(1, n + 1):
# 检查每个起始位置
for start in range(n - length + 1):
# 计算替换该子串后的频次
temp = freq.copy()
for i in range(start, start + length):
temp[input[i]] -= 1
# 检查是否可以通过添加length个字符达到平衡
max_count = max(temp.values())
min_count = min(temp.values())
if max_count - min_count <= length:
# 检查是否可以分配length个字符来达到平衡
needed = sum(max(0, target - count) for count in temp.values())
if needed <= length:
return length
return n
if __name__ == "__main__":
# 测试用例
print(solution("ADDF") == 1) # True
print(solution("ASAFASAFADDD") == 3) # True
print(solution("SSDDFFFFAAAS") == 1) # True
print(solution("AAAASSSSDDDDFFFF") == 0) # True
print(solution("AAAADDDDAAAASSSS") == 4) # True
43、还原原始字符串
def solution(str1):
def can_generate(s, target):
"""检查字符串s是否能通过操作生成目标字符串target"""
current = s
used = {current}
q = [current]
while q and len(q[0]) <= len(target):
current = q.pop(0)
if current == target:
return True
# 尝试所有可能的K
for k in range(len(current)):
next_str = current + current[k:]
if len(next_str) <= len(target) and next_str not in used:
if target.startswith(next_str):
used.add(next_str)
q.append(next_str)
return False
def get_all_prefixes(s):
"""获取字符串的所有可能前缀"""
result = []
for i in range(1, len(s) + 1):
prefix = s[:i]
if can_generate(prefix, s):
result.append(prefix)
return result
# 获取所有可能的前缀
possible_prefixes = get_all_prefixes(str1)
# 如果没有找到可能的前缀,返回原字符串
if not possible_prefixes:
return str1
# 返回最短的可能前缀
return min(possible_prefixes, key=len)
if __name__ == "__main__":
# 测试用例
test_cases = [
"abbabbbabb", # "ab"
"abbbabbbb", # "ab"
"jiabanbananananiabanbananananbananananiabanbananananbananananbananananbanananan", # "jiaban"
"selectecttectelectecttectcttectselectecttectelectecttectcttectectelectecttectcttectectcttectectcttectectcttect", # "select"
"discussssscussssiscussssscussssdiscussssscussssiscussssscussssiscussssscussss", # "discus"
"lflsdjlskjfl" # "lflsdjlskjfl"
]
expected_results = [
"ab",
"ab",
"jiaban",
"select",
"discus",
"lflsdjlskjfl"
]
for i, test_case in enumerate(test_cases):
result = solution(test_case)
print(f"Test case {i + 1}: {result == expected_results[i]}")
44、小E的射击训练
def solution(x: int, y: int) -> int:
# 计算射击点到靶心的距离
distance = (x * x + y * y) ** 0.5
# 如果距离大于10,超出所有环,得0分
if distance > 10:
return 0
# 根据距离确定所在环数
# 使用向上取整,因为距离正好在圆上时应该算作外环
ring = int(distance + 0.99999) # 使用这种方式处理浮点数精度问题
# 计算得分:11减去环数
score = 11 - ring
return score
if __name__ == '__main__':
# 测试样例
print(solution(1, 0) == 10) # True,距离1,在第1环内
print(solution(1, 1) == 9) # True,距离√2≈1.414,在第2环内
print(solution(0, 5) == 6) # True,距离5,在第5环内
print(solution(3, 4) == 6) # True,距离5,在第5环内
# 额外测试用例
print(solution(0, 0) == 10) # 靶心
print(solution(10, 0) == 1) # 第10环边界
print(solution(7, 7) == 1) # 距离约9.899,在第10环内
print(solution(8, 8) == 0) # 距离约11.314,超出所有环
46、大数和中的极值位距离
def add_large_numbers(num1: str, num2: str) -> str:
"""实现大数加法"""
# 将较短的数字在前面补0,使两个数字长度相同
max_len = max(len(num1), len(num2))
num1 = num1.zfill(max_len)
num2 = num2.zfill(max_len)
carry = 0 # 进位
result = []
# 从右向左逐位相加
for i in range(max_len - 1, -1, -1):
digit_sum = int(num1[i]) + int(num2[i]) + carry
carry = digit_sum // 10
result.append(str(digit_sum % 10))
# 处理最后的进位
if carry:
result.append(str(carry))
# 反转结果并转换为字符串
return ''.join(result[::-1])
def find_min_distance(sum_str: str) -> int:
"""在结果字符串中找出最大值和最小值的最小位置差"""
if len(set(sum_str)) == 1: # 如果所有数字都相同
return 0
# 找到最大和最小数字
max_digit = max(sum_str)
min_digit = min(sum_str)
# 记录每个数字最后出现的位置
last_pos = {}
# 记录当前找到的最小距离
min_distance = len(sum_str)
# 遍历字符串,记录位置并更新最小距离
for i, digit in enumerate(sum_str):
if digit == max_digit or digit == min_digit:
# 如果另一个极值已经出现过
for prev_digit, prev_pos in last_pos.items():
if (digit == max_digit and prev_digit == min_digit) or \
(digit == min_digit and prev_digit == max_digit):
min_distance = min(min_distance, i - prev_pos)
last_pos[digit] = i
return min_distance - 1 if min_distance != len(sum_str) else min_distance
def solution(string1: str, string2: str) -> int:
"""主函数:计算两个大数相加后的最大最小值位置差"""
# 计算两数之和
sum_result = add_large_numbers(string1, string2)
# 计算最大最小值的最小位置差
return find_min_distance(sum_result)
if __name__ == "__main__":
# 测试用例
print(solution("111", "222") == 0) # 结果是"333",所有数字相同,差距为0
print(solution("111", "34") == 1) # 结果是"145",最大值5和最小值1的位置差为1
print(solution("999", "1") == 0) # 结果是"1000",最大值1和最小值0的位置差为0
print(solution("525", "474") == 0) # 结果是"999",所有数字相同,差距为0
print(solution("5976762424003073", "6301027308640389") == 6) # 大数测试
# 额外测试用例
print(solution("99", "1") == 0) # 结果是"100",测试进位情况
print(solution("555", "444") == 0) # 结果是"999",测试全相同数字
54、数字翻译成字符串的可能性
def solution(num):
# 转换为字符串,方便处理每一位
s = str(num)
n = len(s)
# dp[i]表示前i个数字的翻译方法数
dp = [0] * (n + 1)
dp[0] = 1 # 空字符串有1种翻译方法
dp[1] = 1 # 第一个数字只有1种翻译方法
for i in range(2, n + 1):
# 当前数字可以单独翻译
dp[i] = dp[i-1]
# 检查当前数字能否与前一个数字组合翻译
two_digits = int(s[i-2:i])
# 组合的数字必须在10-25之间才能翻译
if 10 <= two_digits <= 25:
dp[i] += dp[i-2]
return dp[n]
if __name__ == "__main__":
print(solution(12258) == 5) # True
print(solution(1400112) == 6) # True
print(solution(2110101) == 10) # True
print(solution(25) == 2) # True
print(solution(1023) == 4) # True