[LeetCode] Solve the Equation 解方程
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] Solve the Equation 解方程的更多相关文章
- hdu2199Can you solve this equation?(解方程+二分)
Can you solve this equation? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K ( ...
- 【LeetCode】640. Solve the Equation 解题报告(Python)
[LeetCode]640. Solve the Equation 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemingzhu 个人博客: ht ...
- 【leetcode】640. Solve the Equation
题目如下: 解题思路:本题的思路就是解析字符串,然后是小学时候学的解方程的思想,以"2x+3x-6x+1=x+2",先把左右两边的x项和非x项进行合并,得到"-x+1=x ...
- 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 ...
- python 解方程
[怪毛匠子=整理] SymPy 库 安装 sudo pip install sympy x = Symbol('x') 解方程 solve([2 * x - y - 3, 3 * x + y - 7] ...
- HDU 2199 Can you solve this equation(二分答案)
Can you solve this equation? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K ( ...
- 解方程 2014NOIP提高组 (数学)
解方程 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 输入描述 Input Description 输入文 ...
- HDU 2199 Can you solve this equation?【二分查找】
解题思路:给出一个方程 8*x^4 + 7*x^3 + 2*x^2 + 3*x + 6 == Y,求方程的解. 首先判断方程是否有解,因为该函数在实数范围内是连续的,所以只需使y的值满足f(0)< ...
- hdu 2199:Can you solve this equation?(二分搜索)
Can you solve this equation? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K ( ...
随机推荐
- python爬虫解决gbk乱码问题
今天尝试了下爬虫,爬取一本小说,忘语的凡人修仙仙界篇,当然这样不好,大家要支持正版. 爬取过程中是老套路,先获取网页源代码 # -*- coding:UTF-8 -*- from bs4 import ...
- MySQL之索引详解
这篇博客将要阐述为什么使用b+树作为索引,而不是b树或者其他树 1.什么是b树 (图片来自网络) b树相关特性:⑴关键字分布在整棵树中 ⑵任何一个关键字只出现在一个节点上 ⑶搜索可能在非叶子节点上结束 ...
- 结对作业NO.2
结对NO.2 1. 引言 1.1 项目地址 github 生成的一组好数据 1.2 项目简介 按照老师给的项目要求:"编码实现一个部门与学生的智能匹配的程序".由于数据需要自己生成 ...
- C语言第三周作业---单层循环
一.PTA实验作业 题目1 1.实验代码 int N = 0,i; char sex; float a[9], height; scanf("%d\n", &N); for ...
- 团队第1次作业:Our Team TAH
Team named TAH 不管一个人多么有才能,但是集体常常比他更聪明和更有力. --奥斯特洛夫斯基 *introduce team and teamate 先说说TAH的含义,是 ...
- 201621123050 《Java程序设计》第5周学习总结
1. 本周学习总结 1.1 写出你认为本周学习中比较重要的知识点关键词 答:接口.has-a.comparable 1.2 尝试使用思维导图将这些关键词组织起来.注:思维导图一般不需要出现过多的字. ...
- 2018上C语言程序设计(高级)作业- 第2次作业
作业要求一 提交截图: 6-7: 6-8: 6-9: 7-1: 作业要求二 题目6-7删除字符中数字字符 1.设计思路: (1)第一步:本题要求是删除字符中的数字字符,我的主要思路是通过数组遍历若遇到 ...
- 去掉xcode编译warning:ld: warning: directory not found for option '-L
选择工程, 编译的 (targets) 选择 Build Settings 菜单 查找 Library Search Paths 和 Framework Search Paths, 删掉编译报warn ...
- Android Notification setLatestEventInfo方法已废弃
代替setLatestEventInfo的方法是用Notification.Builder创建Builder对象,通过该对象设置Notification相关属性. otification.Builde ...
- thinkphp框架调用类不存在的方法
thinkphp框架调用类不存在的方法调用类不存在的方法,不会报错,但是也不会执行,这是根据tp框架里面的一个魔术方法,框架里面一共才十几个魔术方法