题目描述

✅ LCP 17. 速算机器人

image-20260929112923919

题意分析

初始 x = 1、y = 0,按字符串从左到右执行指令:A 只更新 x = 2 * x + y,B 只更新 y = 2 * y + x。最终返回两个变量的和,而不是某一个变量。

解法:按题意模拟

核心思路

[!blue]

用 x、y 保存执行完当前指令前缀后的两个数。每次读取下一条指令,只套用它对应的一条公式,另一变量保持不变。右侧表达式使用更新前的值,因此一个条件分支中的一次赋值就能完成操作,不需要同时更新两个变量。

初值与题意一致,而每一步又严格执行当前指令的定义,所以每轮之后,变量都等于相应指令前缀执行后的真实状态。遍历结束时返回 x + y,就是全部指令的结果。

总和还有一个不变量:执行 A 后为 (2 * x + y) + y = 2 * (x + y);执行 B 后为 x + (2 * y + x) = 2 * (x + y)。两种指令都会让总和翻倍,从初始和 1 出发,执行 t 条指令后的和就是 $2^t$。具体顺序可能改变 x、y 各自的值,但不改变最终总和。

解题步骤

  1. 初始化 x=1、y=0。
  2. 依次读取指令,只更新它指定的变量。
  3. 完成后返回两者之和。

题目保证字符只有 A、B,所以代码的另一个分支可以直接处理 B。空字符串不执行任何更新,返回初始和 1;字符串长度最多为 10,总和最多为 1024,普通整数即可保存。

代码实现

class Solution {
    public int calculate(String s) {
        int x = 1;
        int y = 0;

        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);

            // 每条指令只更新一个变量,但两种指令都会使总和翻倍。
            if (c == 'A') {
                x = 2 * x + y;
            } else {
                y = 2 * y + x;
            }
        }

        return x + y;
    }
}
func calculate(s string) int {
    x, y := 1, 0
    for i := 0; i < len(s); i++ {
        // 每条指令只更新一个变量,但两种指令都会使总和翻倍。
        if s[i] == 'A' {
            x = 2*x + y
        } else {
            y = 2*y + x
        }
    }
    return x + y
}

复杂度分析

  • 时间复杂度:$O(\lvert s\rvert+1)$,当前实现逐条模拟。
  • 空间复杂度:$O(1)$。

关键点总结

[!green]

  • 每条指令只执行一条更新公式。
  • 总和每轮翻倍,可作为理解与核对依据。
  • 返回总和,不是单独某个变量。

易错点总结

[!yellow]

  • 初始两个变量都设为零:所有更新后仍是零。
  • 同一轮同时更新 x 和 y:把一条指令变成两次操作。
  • 漏读第一条或最后一条指令:少执行一次翻倍。
  • 只返回 x 或 y:并不是题目要求的总和。

相似题目

题目 难度 关联与区别
50. Pow(x, n) 中等 每条指令都让x+y翻倍,最终是2的指令长度次方;一般幂可用快速幂,本题短输入可直接处理。
转载与许可
作者
链接 https://hgnulb.github.io/blog/2021/41823934
许可 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处!