leetcode-640. 求解方程

152 阅读2分钟

题目

640. 求解方程

难度中等

求解一个给定的方程,将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)
}