📌  相关文章
📜  通过在任何步骤将 N 更改为 2*N 或 N10 来将 N 更改为 1 的最小步骤(1)

📅  最后修改于: 2023-12-03 15:42:01.472000             🧑  作者: Mango

将 N 更改为 1 的最小步骤

题目要求通过将 N 更改为 2*N 或 N10 的方式将 N 变为 1,这是一道典型的数学问题。

解法

考虑倒推,从目标数字 1 开始,倒推回原数字 N,将每个数字变成它的前一个数字,使得最终获得原数字 N。因为每个数字只能变成它的前一个数字,因此每次变化只能除以 2 或除以 10(如果这个数字是 10 的倍数),即

2*N 或 N/10 -> N

尝试从 N = 1 开始倒推,假设现在推到了数字 x,那么它必须符合以下两种情况之一:

  • x = 2*N
  • x = N/10 (如果 N 是 10 的倍数)

根据这两种情况,可以继续倒推下去,直到推回原数字 N。

可以用广度优先搜索(BFS)算法来实现从 1 开始的倒推过程。具体做法是:

  1. 创建一个队列 q,把数字 1 加入队列。
  2. 创建一个哈希表 visited,记录访问过的数字。
  3. 定义一个变量 step,初始化为 0。
  4. 当队列不空时,进行如下操作:
    1. 从队列中取出一个数字 x。
    2. 如果 x = N,则返回 step。
    3. 记录 x 已访问。
    4. 将 x 的下一个数字按照题目规则加入队列中。
    5. 将 step 加 1。

最后返回 step 即为将 N 变为 1 的最小步骤。

下面是 Python 代码实现:

```python
def minSteps(n: int) -> int:
    q = []  # BFS队列
    q.append(1)  # 将数字1入队
    visited = set()  # 记录访问的数字
    visited.add(1)
    step = 0 # 初始步数为0
    while q:
        size = len(q)
        for i in range(size):  # 遍历当前队列,每个元素出队
            cur = q.pop(0)
            if cur == n:  # 如果当前数字已经是N, 则跳出循环返回步数
                return step
            # 将当前数字的下一个数字按题目规则加入队列
            if cur * 2 not in visited:
                q.append(cur * 2)
                visited.add(cur * 2)
            if cur % 10 == 0 and cur // 10 not in visited:
                q.append(cur // 10)
                visited.add(cur // 10)
        step += 1  # 记录步数加1
    return -1  # 如果队列为空,说明无法变为N
```