表示数字的最少运算符
难度:
标签:
题目描述
代码结果
运行时间: 32 ms, 内存: 0.0 MB
/*
* Problem: Given a positive integer x, we need to write an expression using x and operators (+, -, *, /) such that the expression equals a given target value. The goal is to use the minimum number of operators.
*
* Approach:
* 1. This is a complex problem and not particularly well-suited to Java Streams because it requires a recursive search with memoization.
* 2. For demonstration purposes, we show a simplified use of streams in a recursive helper function.
*/
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream;
public class MinOperatorsStream {
private Map<Long, Integer> memo = new HashMap<>();
public int minOperators(int x, int target) {
return helper((long) x, (long) target);
}
private int helper(long x, long target) {
if (x == target) return 0;
if (memo.containsKey(target)) return memo.get(target);
long quotient = target / x;
long remainder = target % x;
int result = Stream.of(
remainder == 0 ? helper(x, quotient) + 1 : Integer.MAX_VALUE,
helper(x, quotient) + (int) remainder + 1,
helper(x, quotient + 1) + (int) (x - remainder) + 1
).min(Integer::compare).orElse(Integer.MAX_VALUE);
memo.put(target, result);
return result;
}
public static void main(String[] args) {
MinOperatorsStream mos = new MinOperatorsStream();
System.out.println(mos.minOperators(3, 19)); // Output: 5
System.out.println(mos.minOperators(5, 501)); // Output: 8
System.out.println(mos.minOperators(100, 100000000)); // Output: 3
}
}
解释
方法:
该题解采用动态规划方法,通过计算当前数值能被表示的最小操作数,逐步递推至目标值。利用正数(pos)和负数(neg)两个变量,分别记录达到当前数值的最小正表达式和最小负表达式所需的运算符数量。通过不断地对目标值 target 进行 x 的除法,计算每步的余数以决定使用加法或乘法的数量,同时也考虑通过余数来决定是否可以通过少量的减法或除法来达到目标。最后,根据最终得到的 pos 和 neg 的值,计算出包括转换方向的运算符总数,并减去一个基础值,得到最小运算符的总数。
时间复杂度:
O(log_x(target))
空间复杂度:
O(1)
代码细节讲解
🦆
如何保证在每次迭代中使用除法和取余得到的当前最小表示是最优的?
▷🦆
在更新pos和neg的过程中,min函数中的各个选项具体代表什么意义?具体是如何通过这些计算达到最少运算符的?
▷🦆
为什么在k为0的初始情况下,将pos和neg设置为cur*2和(x-cur)*2,这里的乘以2是基于什么考虑?
▷🦆
在最后返回结果时,为什么要从min(pos, k + neg)的结果中减去1?
▷