Solve a given equation and return the value of x in the form of string "x=#value". The equation contains only '+', '-' operation, the variable x and its coefficient.

If there is no solution for the equation, return "No solution".

If there are infinite solutions for the equation, return "Infinite solutions".

If there is exactly one solution for the equation, we ensure that the value of x is an integer.

Example 1:

Input: "x+5-3+x=6+x-2"
Output: "x=2"

Example 2:

Input: "x=x"
Output: "Infinite solutions"

Example 3:

Input: "2x=x"
Output: "x=0"

Example 4:

Input: "2x+3x-6x=x+2"
Output: "x=-1"

Example 5:

Input: "x=x+2"
Output: "No solution"

这道题给了我们一个用字符串表示的方程式,让我们求出x的解,根据例子可知,还包括x有无穷多个解和x没有解的情况。解一元一次方程没什么难度,难点在于处理字符串,如何将x的系数合并起来,将常数合并起来,化简成ax=b的形式来求解。博主最开始的思路是先找到等号,然后左右两部分分开处理。由于要化成ax=b的格式,所以左半部分对于x的系数都是加,右半部分对于x的系数都是减。同理,左半部分对于常数是减,右半部分对于常数是加。

那么我们就开始处理字符串了,我们定义一个符号变量sign,初始化为1,数字变量num,初始化为-1,后面会提到为啥不能初始化为0。我们遍历每一个字符,如果遇到了符号位,我们看num的值,如果num是-1的话,说明是初始值,没有更新过,我们将其赋值为0;反之,如果不是-1,说明num已经更新过了,我们乘上当前的正负符号值sign。这是为了区分"-3"和"3+3"这种两种情况,遇到-3种的符号时,我们还不需要加到b中,所以num此时必须为0,而遇到3+3中的加号时,此时num已经为3了,我们要把前面的3加到b中。

遇到数字的时候,我们还是要看num的值,如果是初始值,那么就将其赋值为0,然后计算数字的时候要先给num乘10,再加上当前的数字。这样做的原因是常数不一定都是个位数字,有可能是两位数或者三位数,这样做才能正确的读入数字。我们在遇到数字的时候并不更新a或者b,我们只在遇到符号位或者x的时候才更新。这样如果最后一位是数字的话就会产生问题,所以我们要在字符串的末尾加上一个+号,这样确保了末尾数字会被处理。

遇到x的时候比较tricky,因为可能是x, 0x, -x这几种情况,我们还是首先要看num的值是否为初始值-1,如果是的话,那么就可能是x或-x这种情况,我们此时将num赋值为sign;如果num不是-1,说明num已经被更新了,可能是0x, -3x等等,所以我们要将num赋值为num*sign。这里应该就明白了为啥不能将num初始化为0了,因为一旦初始化为0了,就没法区分x和0x这两种情况了。

那么我们算完了a和b,得到了ax=b的等式,下面的步骤就很简单了,只要分情况讨论得出正确的返回结果即可,参见代码如下:

解法一:

class Solution {
public:
string solveEquation(string equation) {
int a = , b = ;
auto found = equation.find("=");
helper(equation.substr(, found), true, a, b);
helper(equation.substr(found + ), false, a, b);
if (a == && a == b) return "Infinite solutions";
if (a == && a != b) return "No solution";
return "x=" + to_string(b / a);
}
void helper(string e, bool isLeft, int& a, int& b) {
int sign = , num = -;
e += "+";
for (int i = ; i < e.size(); ++i) {
if (e[i] == '-' || e[i] == '+') {
num = (num == -) ? : (num * sign);
b += isLeft ? -num : num;
num = -;
sign = (e[i] == '+') ? : -;
} else if (e[i] >= '' && e[i] <= '') {
if (num == -) num = ;
num = num * + e[i] - '';
} else if (e[i] == 'x') {
num = (num == -) ? sign : (num * sign);
a += isLeft ? num : -num;
num = -;
}
}
}
};

下面这种解法也很不错,也是求ax=b等式中的a和b,但是没有根据等号拆分为左右两部分,而是用一个变量sign来控制是对a和b加还是减,这跟上面解法中的的sign不一样。这里没有专门管正负的变量,而是通过双指针,指向数字的范围,这个数字可以是x的系数,也可以是常量,可以带着正负号,然后通过stoi函数将字符串直接转为整型数,然后乘以sign加到a或b中。变量j会指向数字或者符号,当i大于j时,我们就提取出范围内的数字。当我们遇到x的时候,跟上面一样,要处理+x, -x, 0x的情况,我们看前一位的字符,如果是符号,那么我们直接给a加上符号值;如果是数字,就用上面的办法提取出数字乘以sign加到a中。如果遇到了等号,那么先处理前面的数字(如果有的话),然后flip sign。最后循环结束后,还要考虑最后一位是数字的情况,要加到b中。后面分情况讨论就不多说了,参见代码如下:

解法二:

class Solution {
public:
string solveEquation(string equation) {
int n = equation.size(), a = , b = , sign = , j = ;
for (int i = ; i < n; ++i) {
if (equation[i] == '+' || equation[i] == '-') {
if (i > j) b += stoi(equation.substr(j, i - j)) * sign;
j = i;
} else if (equation[i] == 'x') {
if (i == j || equation[i - ] == '+') {
a += sign;
} else if (equation[i - ] == '-') {
a -= sign;
} else {
a += stoi(equation.substr(j, i - j)) * sign;
}
j = i + ;
} else if (equation[i] == '=') {
if (i > j) b += stoi(equation.substr(j, i - j)) * sign;
sign = -;
j = i + ;
}
}
if (j < n) b += stoi(equation.substr(j)) * sign;
if (a == && a == b) return "Infinite solutions";
if (a == && a != b) return "No solution";
return "x=" + to_string(-b / a);
}
};

类似题目:

Fraction Addition and Subtraction

参考资料:

https://discuss.leetcode.com/topic/95203/concise-java-solution

https://discuss.leetcode.com/topic/95279/c-two-pointers-concise-solution

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] Solve the Equation 解方程的更多相关文章

  1. hdu2199Can you solve this equation?(解方程+二分)

    Can you solve this equation? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ( ...

  2. 【LeetCode】640. Solve the Equation 解题报告(Python)

    [LeetCode]640. Solve the Equation 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemingzhu 个人博客: ht ...

  3. 【leetcode】640. Solve the Equation

    题目如下: 解题思路:本题的思路就是解析字符串,然后是小学时候学的解方程的思想,以"2x+3x-6x+1=x+2",先把左右两边的x项和非x项进行合并,得到"-x+1=x ...

  4. HDU 2199 Can you solve this equation?(二分解方程)

    传送门: http://acm.hdu.edu.cn/showproblem.php?pid=2199 Can you solve this equation? Time Limit: 2000/10 ...

  5. python 解方程

    [怪毛匠子=整理] SymPy 库 安装 sudo pip install sympy x = Symbol('x') 解方程 solve([2 * x - y - 3, 3 * x + y - 7] ...

  6. HDU 2199 Can you solve this equation(二分答案)

    Can you solve this equation? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ( ...

  7. 解方程 2014NOIP提高组 (数学)

    解方程  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond       题目描述 Description 输入描述 Input Description 输入文 ...

  8. HDU 2199 Can you solve this equation?【二分查找】

    解题思路:给出一个方程 8*x^4 + 7*x^3 + 2*x^2 + 3*x + 6 == Y,求方程的解. 首先判断方程是否有解,因为该函数在实数范围内是连续的,所以只需使y的值满足f(0)< ...

  9. hdu 2199:Can you solve this equation?(二分搜索)

    Can you solve this equation? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ( ...

随机推荐

  1. Android开发心得-使用File ExPlorer无法访问系统内部文件

    问题:本机在获得ROOT权限后,使用Eclipse自带的File Explorer访问/data/data下各APP的存储文件,均无法打开.更换另外一个设备后,情况正常.Sumsung的有些机型在获得 ...

  2. layui-row 布局因高度不一致错位问题

    js框架为vue,通过vue去循环生成layui-col-md2;<div class="layui-row layui-col-space1"> <templa ...

  3. 【分布式系列之dubbo】dubbo管理工具dubbo-admin安装使用

    一.安装完成后界面显示 二.安装 1.下载dubbo-admin安装包 2.修改WEB-INF下的dubbo.properties文件内容 dubbo.registry.address=zookeep ...

  4. Django—urls系统:urls基础

    Django的urls系统简介 Django 1.11版本 URLConf官方文档 URL配置(URLconf)就像Django 所支撑网站的目录.它的本质是URL与要为该URL调用的视图函数之间的映 ...

  5. 新手使用mac上的textedit写HTML时遇到的问题及解决办法

    刚开始在mac上学习HTML,总结一下遇到的问题和解决办法 问题:使用textedit编写html,在网页上却仍然显示的是代码. 解决办法: 打开textedit后打开文本编辑 选择偏好设置 按如图所 ...

  6. alpha冲刺第十天

    一.合照 二.项目燃尽图 三.项目进展 之前卡住的注册无法插入数据的问题解决 可以呈现多条数据内容了,首页文章内容呈现,问答界面问题内容呈现 四.明日规划 很多没有完善的,后面还是要继续整改 五.问题 ...

  7. 学习ASP.NET Core Razor 编程系列四——Asp.Net Core Razor列表模板页面

    学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...

  8. JAVA_SE基础——44.抽象类的练习

    抽象类要注意的细节: 1. 如果一个函数没有方法体,那么该函数必须要使用abstract修饰,把该函数修饰成抽象 的函数..2. 如果一个类出现了抽象的函数,那么该类也必须 使用abstract修饰. ...

  9. 逆向集录_00_不同程序OEP特征总结

    在分析/逆向 程序时,如果事先知道这类程序的一些特征,那将会是事半功倍的: 分析/逆向 程序,和写程序不同,比喻的话:写程序像在作案,分析/逆向 程序就像是在破案,对破案来讲,重在假想和推理: 特征1 ...

  10. href的理解

    您搜索的项目暂未上线,可直接<a style="color: #ff0000;" onclick="onlineTalk();" href="j ...