疯狂整数统计|豆包MarsCode AI刷题

41 阅读3分钟

在这个编程问题中,我们需要计算小于或等于给定整数N的“疯狂整数”的数量。“疯狂整数”是指只包含数字“1”和“2”的整数。我们的目标是编写一个函数count_crazy_numbers(N: int) -> int,该函数接受一个整数N作为输入,并返回所有小于或等于N的非负疯狂整数的数量。

我们从一个包含初始疯狂整数1和2的队列开始,不断扩展这个队列,从而找到所有可能的疯狂整数。在扩展过程中,我们检查每个生成的疯狂整数是否小于或等于N,如果是,则将其计数,并将其作为新的疯狂整数加入队列中,以便进一步扩展。

知识点

广度优先搜索(BFS):BFS是一种遍历或搜索图或树数据结构的算法。它从一个起始节点开始,首先访问所有相邻的节点,然后再从这些相邻节点出发,访问它们的未访问的相邻节点,以此类推,直到所有节点都被访问到。在这个问题中,我们将BFS应用于生成疯狂整数的过程。

代码详解

以下是实现上述思路的Python代码:

def count_crazy_numbers(N: int) -> int:
# 初始化计数器,如果N小于1,则返回0
if N < 1:
    return 0

# 初始化队列和计数器
queue = [1, 2] if N >= 2 else [1] if N == 1 else []
count = len(queue)  # 如果N>=1,则至少包含1这个疯狂整数

# 广度优先搜索
while queue:
    num = queue.pop(0)  # 从队列中取出一个疯狂整数
    
    # 检查num*10+1和num*10+2是否小于等于N,并更新队列和计数器
    if num * 10 + 1 <= N:
        queue.append(num * 10 + 1)
        count += 1
    if num * 10 + 2 <= N:
        queue.append(num * 10 + 2)
        count += 1

# 返回计数结果
return count

# 测试函数
def solution(N: int) -> int:
# 计算小于或等于N的疯狂整数的个数
return count_crazy_numbers(N)

# 验证结果
print(solution(N=21) == 5)  # 输出:True
print(solution(N=50) == 6)  # 输出:True
print(solution(N=5) == 2)   # 输出:True

在上述代码中,我们首先检查输入整数N是否小于1,如果是,则直接返回0,因为不存在小于1的疯狂整数。然后,我们初始化一个队列queue来存储待扩展的疯狂整数。如果N大于等于2,我们将1和2都加入队列;如果N等于1,我们只将1加入队列;如果N小于1,则队列为空。同时,我们初始化一个计数器count来记录已经找到的疯狂整数的数量。

接下来,我们进入广度优先搜索的循环。在每次循环中,我们从队列中取出一个疯狂整数num,并检查num10+1和num10+2是否小于等于N。如果是,则将它们分别加入队列,并更新计数器。这个过程会一直进行,直到找到所有可能的疯狂整数。

最后,我们返回计数器的值作为结果。在测试函数中,我们调用count_crazy_numbers函数来计算小于或等于给定N的疯狂整数的数量,并验证结果是否正确。

注意:如果单纯地遍历范围内的数字并检查是否至多包含1和2两种数字,在范围较小的时候可以实现,并且易于理解,然而,当范围很大时,因为这种方法速度较慢,很可能导致运行超时,因此应该由一个疯狂整数在末尾加1或2来生成新的疯狂整数,减少运行时间。