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. 【HTTP协议】---HTTP协议详解

    HTTP协议详解 一.HTTP简介 1.HTTP协议,即超文本传输协议(Hypertext transfer protocol).是一种详细规定了浏览器和万维网(WWW = World Wide We ...

  2. python全栈开发-Day11 迭代器、生成器、面向过程编程

    一. 迭代器 一 .迭代的概念 迭代器即迭代的工具,那什么是迭代呢? 迭代是一个重复的过程,每次重复即一次迭代,并且每次迭代的结果都是下一次迭代的初始值 while True: #只是单纯地重复,因而 ...

  3. JSP、Servlet、JDBC学习笔记

    WEB的学习 * 服务器 * 网络的架构(面试题) * C/S client/server 客户端/服务器端 例子:QQ 快播 暴风影音 * 优点:交互性好,服务器压力小. * 缺点:客户端更新了,下 ...

  4. linux分析、诊断及调优必备的“杀器”之二

    先说明下,之所以同类内容分成多篇文章,不是为了凑篇数,而是为了便于自己和大家阅读,下面继续: 7.sar The sar command is used to collect, report, and ...

  5. nodejs安装和卸载

    Ubuntu 上安装 Node.js 方式一:直接安装    一.安装 1.$ sudo apt-get install nodejs2.$ sudo apt-get install npm二.升级 ...

  6. Software Engineering-HW1

    title: Software Engineering-HW1 date: 2017-09-13 15:41:13 tags: HW --- 阅读随笔 在<徐宥:掉进读书的兔子洞>里面, ...

  7. Mysql5.7.17中文乱码问题

    写Java web调数据库,老是出现汉字乱码,一直没理睬,今天决定好好"整治"一下,却发现并没有那么简单.从网上找的方法,大部分都尝试了一遍都有一些问题. 有的改完了,数据库启动不 ...

  8. mobiscroll2.5.4 日期组件

    <script type="text/javascript"> function setCss(o) { $('input:jqmData(role="dat ...

  9. 201621123057 《Java程序设计》第9周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结集合与泛型相关内容. 在上一周的总结上做了一点补充 1.2 选做:收集你认为有用的代码片段 2. 书面作业 本次作业题集集合 1. ...

  10. 201621123043 《Java程序设计》第11周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 2. 书面作业 本次PTA作业题集多线程 1. 源代码阅读:多线程程序BounceThread 1.1 BallR ...