算法--解方程

226 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第13天,点击查看活动详情

题目

leetcode 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"

提示:

3 <= equation.length <= 1000 equation 只有一个 '='. equation 方程由整数组成,其绝对值在 [0, 100] 范围内,不含前导零和变量 'x' 。

题解

整体思路是将x与数字分开,提取+,-的值,变成一个左右等式nx=m方便我们计算。最后返回x=m/n,根据mn的不同值进行分析不同的返回结果。题目的难点在于如何拆分+-两边的变量以及将他们进行数学运算得出m,n

var solveEquation = function(equation) {
    const equations = equation.split("=");
    const els = [0,0];
    const left = equations[0].split('');
    const right = equations[1].split('');
    const add = [''];
    const dec = [''];
    
    if (left[0] !== '+' && left[0] !== "-") {
        left.splice(0,0,"+")
    }
    if (right[0] !== '+' && right[0] !== "-") {
        right.splice(0,0,"+")
    }
    let i = 0;
    while (i < left.length) {
        if (left[i] === "+") {
            i++;
            while (left[i] !== "+" && left[i] !== "-" ) {
                add[add.length - 1] += left[i];
                i++;
                if (i >= left.length) {
                    break;
                }

            }
            add.push('');
        }else{
            i++;
            while (left[i] !== "+" && left[i] !== "-" ) {
                dec[dec.length - 1] += left[i];
                i++;
                if (i >= left.length) {
                    break;
                }
            }
            dec.push('');
        }
    }
    i = 0;
    while (i < right.length) {
        if (right[i] === "+") {
            i++;
            while (right[i] !== "+" && right[i] !== "-" ) {
                dec[dec.length - 1] += right[i];
                i++;
                if (i >= right.length) {
                    break;
                }
            }
            dec.push('');
        }else{
            i++;
            while (right[i] !== "+" && right[i] !== "-" ) {
                add[add.length - 1] += right[i];
                i++;
                if (i >= right.length) {
                    break;
                }
            }
            add.push('');
        }
    }
    for (let i = 0; i < add.length - 1; i++) {
        if (add[i].includes('x')) {
            if (add[i].length === 1) {
                els[0] += 1;
            }else{
                const num = parseInt(add[i].split('x')[0])
                els[0] += num;
            }
        }else{
            els[1] += parseInt(add[i]);
        }
    }
    for (let i = 0; i < dec.length - 1; i++) {
        if (dec[i].includes('x')) {
            if (dec[i].length === 1) {
                els[0] -= 1;
            }else{
                const num = parseInt(dec[i].split('x')[0])
                els[0] -= num;
            }
        }else{
            els[1] -= parseInt(dec[i]);
        }
        
    }
    if (els[0] === 0) {
        if (els[1] === 0) {
            return "Infinite solutions";
        }else{
            return "No solution";
        }
    }else{
        if (els[1] === 0) {
            return "x=0"
        }else{
            return `x=${-els[1]/els[0]}`
        }
    }
};


代码详解

第一步初始化:将等式分为左边和右边两个数学式。定义变量elsx的量和数字的量,数组add为累加的集合,数组dec为累减的集合。

第二步归类:首先对第一位进行处理,当第一位是正数的时候通常不好处理,所以我们在前面手动加上+号更加符合逻辑。根据加号后面的数字进行字符串拼接得出一个加数每次的运算符号为分割点。dec数组的处理方式和add是一样的。

第三步运算:在得出adddec数组之后即可对其数学运算。然后就是处理x运算的时候需要把x取出。尝试使用parseInt进行转换的时候会有一个特例0x此时就是NAN所以我们要特殊处理一下。用字符串分割进行取值。将变量x的倍数归为els的第一位,常量保存在els的第二位。

第四步结果分析:当els的变量部分为0时,如果常量也为0那么就有无限解,如果常量不为0则没有解。当els的变量部分不为0时,如果常量为0则x=0,否则就是正常解。