640. 求解方程
解题过程
INFO
题目链接 求解一个给定的方程,将x以字符串 "x=#value" 的形式返回。该方程仅包含 '+' , '-' 操作,变量 x 和其对应系数。 如果方程没有解或存在的解不为整数,请返回 "No solution" 。如果方程有无限解,则返回 “Infinite solutions” 。 题目保证,如果方程中只有一个解,则 'x' 的值是一个整数
javascript
/**
* @link https://leetcode.cn/problems/solve-the-equation/
* @title 640. 求解方程
* @description 求解一个给定的方程,将x以字符串 "x=#value" 的形式返回。该方程仅包含 '+' , '-' 操作,变量 x 和其对应系数。
如果方程没有解或存在的解不为整数,请返回 "No solution" 。如果方程有无限解,则返回 “Infinite solutions” 。
题目保证,如果方程中只有一个解,则 'x' 的值是一个整数
* @param {string} equation
* @return {string}
*/
// 解法一
// 思路:暴力破解法:根据题目意思写出所有情况然后计算
// 第一步:获取方程左右两边元素数组,包括计算符号,默认为加
// 第二步:计算方程左右边公式最简化,变量x和其他常量计算最终值
// 第三步:将右边变量移动到左边并改变符号,将左边常量移动到右边并改变符号
// 第四步:计算最终值,左边变量计算,右边常量计算,然后左边变量求值
var solveEquation = function (equation) {
// 第一步:
const [leftExp, rightExp] = equation.split('=')
const leftArr = leftExp.match(/-?\d+x|-?\d+|-?x/g)
const rightArr = rightExp.match(/-?\d+x|-?\d+|-?x/g)
// 第二步
// 存储计算后左边变量和常量值
let leftCounts = new Array(2).fill(0)
for (const num of leftArr) {
if (num.includes('x')) {
// 变量x
const nanNum = num.includes('0') ? 0 : (num.includes('-') ? -1 : 1)
leftCounts[0] += parseInt(num) || nanNum
} else {
// 常量
leftCounts[1] += parseInt(num)
}
}
// 存储计算后右边变量和常量值
let rightCounts = new Array(2).fill(0)
for (const num of rightArr) {
if (num.includes('x')) {
// 变量x
const nanNum = num.includes('0') ? 0 : (num.includes('-') ? -1 : 1)
rightCounts[0] += parseInt(num) || nanNum
} else {
// 常量
rightCounts[1] += parseInt(num)
}
}
// 第三步
const leftRes = leftCounts[0] - rightCounts[0]
let rightRes = rightCounts[1] - leftCounts[1]
// 第四步
if (leftCounts[0] === rightCounts[0]) {
if (leftCounts[1] === rightCounts[1]) {
return 'Infinite solutions'
}
return 'No solution'
} else {
rightRes = rightRes / leftRes
if (Number.isInteger(rightRes)) {
return 'x=' + rightRes
} else {
return 'No solution'
}
}
}
// 解法二
// 思路:来自题解:通过遍历字符串,合并同类项为类似ax+b=0形式处理,然后最终计算判断
var solveEquation = function (equation) {
// variable:x的系数,constant:最终常量,strConst:当前遍历的字符,sign:当前计算符号位,left:当前右边值计算符号位,hasC:是否计算了系数或常量
let variable = 0, constant = 0, strConst = 0, sign = 1, left = 1, hasC = false
for (let str of equation) {
switch (str) {
case 'x':
variable += hasC ? sign * left * strConst : sign * left, strConst = 0, hasC = false
break;
case '+':
constant += sign * left * strConst, strConst = 0, sign = 1, hasC = false
break;
case '-':
constant += sign * left * strConst, strConst = 0, sign = -1, hasC = false
break;
case '=':
constant += sign * left * strConst, strConst = 0, sign = 1, left = -1, hasC = false
break
default:
// 变量系数或常量
strConst = strConst * 10 + (str - '0'), hasC = true
break
}
}
constant += sign * left * strConst
return variable === 0 ? constant === 0 ? "Infinite solutions" : "No solution" : "x=" + -constant / variable
}
// const result = solveEquation ('x+5-3+x=6+x-2') // x=2
// const result = solveEquation ('2x=x') // x=0
// const result = solveEquation ('2x+3x-6x=x+2') // x=-1
// const result = solveEquation ('x=x+2') // "No solution"
// const result = solveEquation ('-x=-1') // x=1
const result = solveEquation('x=x') // Infinite solutions
// const result = solveEquation ('0x=0') // Infinite solutions
console.log(result)
解题感受
题目理解不难,但是做起来比较复杂。暴力破解只需要把思路写出来基本就能做出来了。其他解法没有去想,因为这种题目比较费时间,没有特别的技巧。看到题解的一种解法会简单很多,直接遍历计算字符串的字符即可,一次性遍历即可解决,执行效果还不错就写了一遍
优质题解
- https://leetcode.cn/problems/solve-the-equation/solution/qiu-jie-fang-cheng-by-leetcode-solution-knct/
- https://leetcode.cn/problems/solve-the-equation/solution/by-ac_oier-fvee/
- https://leetcode.cn/problems/solve-the-equation/solution/by-youyou-v-cmrh/
- https://leetcode.cn/problems/solve-the-equation/solution/fang-cheng-axbzheng-ze-biao-da-shi-new-f-n21k/