Skip to content

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)

解题感受

题目理解不难,但是做起来比较复杂。暴力破解只需要把思路写出来基本就能做出来了。其他解法没有去想,因为这种题目比较费时间,没有特别的技巧。看到题解的一种解法会简单很多,直接遍历计算字符串的字符即可,一次性遍历即可解决,执行效果还不错就写了一遍

优质题解