字节跳动高频面试算法题
1、题目描述
给定集合
A
=
{
x
∈
N
∣
0
≤
x
≤
9
}
A = \{x \in \mathbb{N} \,|\, 0 \leq x \leq 9\}
A={x∈N∣0≤x≤9}和一个数字
n
n
n,请利用集合
A
A
A中的元素构造出小于
n
n
n的最大数,集合中的每个元素可以无限使用。
样例 1:A={1, 2, 9, 4},n=2533,返回 2499。
样例 2:A={1, 2, 5, 4},n=2543,返回 2542。
样例 3:A={1, 2, 5, 4},n=2541,返回 2525。
样例 4:A={1, 2, 9, 4},n=2111,返回 1999。
样例 5:A={5, 9},n=5555,返回 999。
二、解题思路
构造策略: 贪心+回溯
- 从高位开始遍历,对每一位先尝试使用相同数字,除了最后一位.
- 如果没有相同的数字时,尝试是否有比当前数字更小的
- 1). 有的话选更小的数字里最大的,剩下的用最大数字。
2). 都没有就向前回溯看前一个有没有更小的。如果一直回溯到第一个数字都没有更小的数字,就用位数更少的全都是最大数字的数。 - 处理一些特殊情况:
①能够完全构造出n——>把问题转换为构造n-1。
②n的最高位数都比集合A中的所有数小,那么构造出的位数会比n少一位。——>每一位都填A中最大的数。
③特殊判断一下回溯到最高位时,出现前导0的情况。——>和情况②类似。
三、Python代码实现
# 这道题更多的是在操作字符串
# 示例 1:A={1, 2, 9, 4},n=2533,返回 2499。
def find_max_number(A, n):
A.sort(reverse=True)
n_str = str(n)
# 特判一种情况, 如果n中的每一个数字都在A集合里,那么我去构造n-1才行. 因为题目要求是严格小于,而不是小于等于
flag_in = True
for d in n_str:
if int(d) not in A:
flag_in = False
break
if flag_in:
n -= 1
n_str = str(n)
# 预处理10个数(0-9),从集合A中获取小于等于给定数字d的最大数字,并存在mp里
mp = {}
for i in range(10):
flag = False # 记录是否找到
for j in A:
if j <= i:
mp[str(i)] = j # 第一个小于等于i的数字是集合A中的j
flag = True
break
if not flag:
mp[str(i)] = -1 # 说明没有小于等于i的数字
ans = ""
flag_eql = False # 记录后续是否需要全部取A集合的最大值
flag_back = False # 记录当前是否处于回溯状态
idx = 0
while idx < len(n_str) and idx >= 0:
if flag_eql:
ans += str(A[0])
idx += 1
continue
d = n_str[idx] if not flag_back else str(int(n_str[idx]) - 1)
if idx == 0 and mp[d] == 0:
idx -= 1
break
if mp[d] != -1:
if not flag_back:
if mp[d] == int(d): # 有相同数字
pass
else: # 没有相同的数字, 但是存在比d小的数, 那么后续全部取最大值即可
flag_eql = True
else:
flag_back = False
flag_eql = True
ans += str(mp[d]) # 从mp[d]中构造一位新的数字填入
idx += 1
else: # 需要向前回溯一位
idx -= 1
ans = ans[:-1]
flag_back = True
if idx < 0:
ans = str(A[0]) * (len(n_str) - 1)
return ans
test_cases_corrected = [
([1, 2, 9, 4], 2533),
([1, 2, 5, 4], 2543),
([1, 2, 5, 4], 2541),
([1, 2, 9, 4], 2111),
([5, 9], 5555),
([2,4,5],24131),
([0,7,8],312),
([1,3,5,7],2410)
]
results_corrected = [find_max_number(A, n) for A, n in test_cases_corrected]
print(results_corrected)
四、参考链接
参考博客链接:小于 n 的最大数