题目
难度中等
求解一个给定的方程,将x以字符串 "x=#value" 的形式返回。该方程仅包含 '+' , '-' 操作,变量 x 和其对应系数。
如果方程没有解,请返回 "No solution" 。如果方程有无限解,则返回 “Infinite solutions” 。
题目保证,如果方程中只有一个解,则 'x' 的值是一个整数。
示例 1:
输入: equation = "x+5-3+x=6+x-2"
输出: "x=2"
示例 2:
输入: equation = "x=x"
输出: "Infinite solutions"
示例 3:
输入: equation = "2x=x"
输出: "x=0"
思路
本题就是对输入字符串遍历,进行细致的分类处理即可,难度其实不大,就是过程比较繁琐罢了
整体的思路:将等式右边移到左边(右边的算式符号取反),然后对字符串进行扫描,计算出总的 x 的系数 和 常量值 的大小,结果就显而易见了
一些细节
- 要注意一下 0x 和 x 两者处理逻辑的不同
- x 系数为 0 的同时 常数值也为 0 -> Infinite solutions
x 系数为 0 但是 常数值不为 0 -> No solution - 可以利用一个变量 pos 记录此时扫描的位置处于等号前还是等号后,以此决定是否对符号取反
solution1 是定义了一个额外的函数 update 来处理 x 系数 和 常数值 的更新
solution2 是来自 leetcode 的官方题解,直接对字符串进行处理,思路更加清晰
两者思路基本完全是一样的
实现
solution1
func solveEquation(equation string) string {
x, val, tmp := 0, 0, 0
op, pos := 1, 1
isX := false
update := func() {
if isX {
x += (tmp * op * pos)
} else {
val += (tmp * op * pos)
}
tmp = 0
isX = false
}
for i := 0; i < len(equation) ; i++ {
switch equation[i] {
case '+':
update()
op = 1
case '-':
update()
op = -1
case 'x':
if tmp == 0 && (i == 0 || equation[i-1] != '0') {
tmp = 1
}
isX = true
case '=':
update()
op, pos = 1, -1
default:
v := int(equation[i] - '0')
tmp = 10 * tmp + v
}
}
update()
if x == 0 {
if val == 0 {
return "Infinite solutions"
}
return "No solution"
}
return fmt.Sprintf("x=%d", val / x * (-1))
}
solution2: leetcode官方题解
func solveEquation(equation string) string {
factor, val := 0, 0
i, n, sign := 0, len(equation), 1 // 等式左边默认系数为正
for i < n {
if equation[i] == '=' {
sign = -1 // 等式右边默认系数为负
i++
continue
}
s := sign
if equation[i] == '+' { // 去掉前面的符号
i++
} else if equation[i] == '-' {
s = -s
i++
}
num, valid := 0, false
for i < n && unicode.IsDigit(rune(equation[i])) {
valid = true
num = num*10 + int(equation[i]-'0')
i++
}
if i < n && equation[i] == 'x' { // 变量
if valid {
s *= num
}
factor += s
i++
} else { // 数值
val += s * num
}
}
if factor == 0 {
if val == 0 {
return "Infinite solutions"
}
return "No solution"
}
return "x=" + strconv.Itoa(-val/factor)
}