文章目录
题目
标题和出处
标题:坏了的计算器
出处:991. 坏了的计算器
难度
4 级
题目描述
要求
有一台坏计算器,初始时显示整数 startValue \texttt{startValue} startValue,可以执行以下两种操作:
- 双倍:将显示屏上的数字乘以 2 \texttt{2} 2;
- 递减:将显示屏上的数字减 1 \texttt{1} 1。
给定两个整数 startValue \texttt{startValue} startValue 和 target \texttt{target} target,返回在计算器上显示数字 target \texttt{target} target 所需的最小操作数。
示例
示例 1:
输入: startValue = 2, target = 3 \texttt{startValue = 2, target = 3} startValue = 2, target = 3
输出: 2 \texttt{2} 2
解释:先双倍,再递减, 2 → 4 → 3 \texttt{2} \rightarrow \texttt{4} \rightarrow \texttt{3} 2→4→3。
示例 2:
输入: startValue = 5, target = 8 \texttt{startValue = 5, target = 8} startValue = 5, target = 8
输出: 2 \texttt{2} 2
解释:先递减,再双倍, 5 → 4 → 8 \texttt{5} \rightarrow \texttt{4} \rightarrow \texttt{8} 5→4→8。
示例 3:
输入: startValue = 3, target = 10 \texttt{startValue = 3, target = 10} startValue = 3, target = 10
输出: 3 \texttt{3} 3
解释:先双倍,再递减,最后双倍, 3 → 6 → 5 → 10 \texttt{3} \rightarrow \texttt{6} \rightarrow \texttt{5} \rightarrow \texttt{10} 3→6→5→10。
数据范围
- 1 ≤ startValue, target ≤ 10 9 \texttt{1} \le \texttt{startValue, target} \le \texttt{10}^\texttt{9} 1≤startValue, target≤109
解法
思路和算法
如果正向计算如何从 startValue \textit{startValue} startValue 到达 target \textit{target} target,则由于乘法的情况较为复杂,因此需要考虑多种可能的情况。
可以考虑反向操作,每次反向操作可以将当前整数除以 2 2 2 或加 1 1 1,除以 2 2 2 的操作只有在当前整数是偶数的情况下才能执行,计算从 target \textit{target} target 到达 startValue \textit{startValue} startValue 的最小反向操作数。以下所说的操作均为反向操作。
当 target \textit{target} target 是奇数时,只能将 target \textit{target} target 加 1 1 1。当 target \textit{target} target 是偶数时,可以将 target \textit{target} target 除以 2 2 2 或加 1 1 1,因此需要对 target \textit{target} target 是偶数的情况分别考虑两种操作,计算最小操作数。
-
如果 startValue < target \textit{startValue} < \textit{target} startValue<target,则当 target \textit{target} target 是偶数时应将 target \textit{target} target 除以 2 2 2。如果将 target \textit{target} target 执行两次加 1 1 1 再除以 2 2 2,则需要三次操作,可以替换成等效的将 target \textit{target} target 除以 2 2 2 再加 1 1 1,只需要两次操作,因此将 target \textit{target} target 除以 2 2 2 的情况下可以得到最小操作数。
-
如果 startValue > target \textit{startValue} > \textit{target} startValue>target,则将 target \textit{target} target 加 1 1 1 直到等于 startValue \textit{startValue} startValue 是操作数最小的做法。如果当 target \textit{target} target 是偶数时将 target \textit{target} target 除以 2 2 2,则会将 target \textit{target} target 减小,到达 startValue \textit{startValue} startValue 需要更多次操作。
根据上述分析,可以使用贪心的思想模拟反向操作并计算最小操作数。具体做法如下。
-
当 startValue < target \textit{startValue} < \textit{target} startValue<target 时,如果 target \textit{target} target 是奇数则将 target \textit{target} target 加 1 1 1,如果 target \textit{target} target 是偶数则将 target \textit{target} target 除以 2 2 2,每次操作之后将操作数加 1 1 1。重复该操作直到 startValue ≥ target \textit{startValue} \ge \textit{target} startValue≥target。
-
当 startValue ≥ target \textit{startValue} \ge \textit{target} startValue≥target 时,需要将 target \textit{target} target 执行 startValue − target \textit{startValue} - \textit{target} startValue−target 次加 1 1 1,将操作数加 startValue − target \textit{startValue} - \textit{target} startValue−target。
-
上述操作结束之后,操作数即为最小操作数。
代码
java
class Solution {
public int brokenCalc(int startValue, int target) {
int operations = 0;
while (startValue < target) {
if (target % 2 != 0) {
target++;
} else {
target /= 2;
}
operations++;
}
operations += startValue - target;
return operations;
}
}
复杂度分析
-
时间复杂度: O ( log target ) O(\log \textit{target}) O(logtarget),其中 target \textit{target} target 是给定的目标值。每次对 target \textit{target} target 的操作仅限于除以 2 2 2 或加 1 1 1,由于不可能出现连续两次加 1 1 1 操作,因此操作次数是 O ( log target ) O(\log \textit{target}) O(logtarget),每次操作的时间是 O ( 1 ) O(1) O(1)。
-
空间复杂度: O ( 1 ) O(1) O(1)。