您的位置:首页 > 其它

leetcode 640. Solve the Equation

2017-08-17 20:22 591 查看
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"

这道题主要的是考察字符串的解析能力。
public String solveEquation(String equation) {
String[] leftAndRight=equation.split("=");
int[] left=solve(leftAndRight[0]);
int[] right=solve(leftAndRight[1]);
int x_xishu=left[0]-right[0];
int changshu=right[1]-left[1];
if(x_xishu==0&&changshu!=0){
return "No solution";
}
if(x_xishu==0&&changshu==0){
return "Infinite solutions";
}
int num=changshu/x_xishu;
return "x="+num;
}

//int[0]返回当前表达式中x的系数
//int[1]返回当前表达式中的常数大小
public int[] solve(String s){
int x_xishu=0;
int changshu=0;
int begin=0;
int end=1;
char fuhao='+';
if(s.charAt(0)=='-'){
fuhao='-';
begin=1;
end=2;
}
while (end <= s.length()) {
while (end < s.length() && s.charAt(end) != '+' && s.charAt(end) != '-') {
end++;
}
String the=s.substring(begin,end);
if(the.indexOf('x')!=-1){//是系数
String numString=the.substring(0, the.indexOf('x'));
int num=1;
if(!numString.equals("")){
num=Integer.parseInt(numString);
}
if(fuhao=='+'){
x_xishu+=num;
}
else{
x_xishu-=num;
}
}
else{//是常数
int num=Integer.parseInt(the);
if(fuhao=='+'){
changshu+=num;
}
else{
changshu-=num;
}
}
if(end<s.length()){
fuhao = s.charAt(end);
}
begin=end+1;
end=begin+1;
}
return new int[]{x_xishu,changshu};
}
还有大神巧妙地运用了regrex中的奇淫技巧。
比如:x +5 -2x = 6 -3x; 那么运用了 rex 之后,

左边的表达式 : tokens= { x, +5, -2x }; x的系数 = 1-2 =-1; 常数 = 5;

右边的表达式: tokens= { 6, -3x }; x的系数 = -3; 常数 = 6;

public String solveEquation(String equation) {
int[] res = evaluateExpression(equation.split("=")[0]),
res2 = evaluateExpression(equation.split("=")[1]);
res[0] -= res2[0];
res[1] = res2[1] - res[1];
if (res[0] == 0 && res[1] == 0) return "Infinite solutions";
if (res[0] == 0) return "No solution";
return "x=" + res[1]/res[0];
}

public int[] evaluateExpression(String exp) {
String[] tokens = exp.split("(?=[-+])");
int[] res =  new int[2];
for (String token : tokens) {
if (token.equals("+x") || token.equals("x")) res[0] += 1;
else if (token.equals("-x")) res[0] -= 1;
else if (token.contains("x")) res[0] += Integer.parseInt(token.substring(0, token.indexOf("x")));
else res[1] += Integer.parseInt(token);
}
return res;
}


为啥 exp.split("(?=[-+])"); 得到的是包含+/-的token呢?可以看看stackoverflow的解答:https://stackoverflow.com/questions/10804732/what-is-the-difference-between-and-in-regex


what
is the difference between ?:, ?! and ?= in regex?



up
vote55down
votefavorite

32

I searched for the meaning of these expressions but couldn't understand the exact differnce between them. This is what they say:

?:
Match
expression but do not capture it.

?=
Match
a suffix but exclude it from capture.

?!
Match
if suffix is absent.

I tried using these in simple RegEx and got similar results for all. example: the following 3 expressions give very similar results.

[a-zA-Z0-9._-]+@[a-zA-Z0-9-]+(?!\.[a-zA-Z0-9]+)*


[a-zA-Z0-9._-]+@[a-zA-Z0-9-]+(?=\.[a-zA-Z0-9]+)*


[a-zA-Z0-9._-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9]+)*


javascript regex
shareimprove
this question
edited Sep
10 '15 at 16:42





Alan
Moore

55k970123

asked May
29 '12 at 18:33





RK
Poddar

5502718

Please show us your test case. They
should not give the same results. – Bergi May
29 '12 at 18:41
@sepp2k, it same similar results in
few case, one of them mentioned in the question. – RK
Poddar May
29 '12 at 18:41
@Bergi, i tested it with random data,
containing english words, phone numbers, urls, e-mail addresses, numbers, etc.. – RK
Poddar May
29 '12 at 18:43
4
@RKAgarwal Ah, I see what you did there.
You added a
*
after
the groups, so they're simply ignored. – sepp2k May
29 '12 at 18:44
noobie
note: you'd only use these at the start of parenthesis, and parenthesis form a capturing group (different parenthesis sets extract different sections of text). – Ryan
Taylor Jun
7 at 19:06
add
a comment


4 Answers

activeoldestvotes

up
vote62down
voteaccepted
The difference between
?=
and
?!
is
that the former requires the given expression to match and the latter requires it to not match.
For example
a(?=b)
will
match the "a" in "ab", but not the "a" in "ac". Whereas
a(?!b)
will
match the "a" in "ac", but not the "a" in "ab".

The difference between
?:
and
?=
is
that
?=
excludes
the expression from the entire match while
?:
just
doesn't create a capturing group. So for example
a(?:b)
will
match the "ab" in "abc", while
a(?=b)
will
only match the "a" in "abc".
a(b)
would
match the "ab" in "abc" and create a capture containing the "b".

shareimprove
this answer
answered May
29 '12 at 18:43





sepp2k

252k31546565



up
vote42down
vote
?:  is for non capturing group
?=  is for positive look ahead
?!  is for negative look ahead
?<= is for positive look behind
?<! is for negative look behind


Please check here: http://www.regular-expressions.info/lookaround.html for
very good tutorial and examples on lookahead in regular expressions.

shareimprove
this answer
answered May
29 '12 at 18:38





anubhava

439k37214285

12
Yet JavaScript does not know lookbehind. – Bergi May
29 '12 at 18:45
add
a comment
up
vote6down
vote
Try matching
foobar
against
these:
/foo(?=b)(.*)/
/foo(?!b)(.*)/


The first regex will match and will return "bar" as first submatch —
(?=b)
matches
the 'b', but does not consume it, leaving it for the following parentheses.

The second regex will NOT match, because it expects "foo" to be followed by something different from "bar".

shareimprove
this answer
answered May
29 '12 at 18:42





lanzz

27.9k65682

add
a comment
这道题有solutions:https://leetcode.com/problems/solve-the-equation/solution/ (表示不太想看T_T)


Solution


Approach #1 Partioning Coefficients [Accepted]

In the current approach, we start by splitting the given equationequation based
on
=
sign. This way, we've separated the left and right hand side of this equation. Once
this is done, we need to extract the individual elements(i.e.
x
's and the numbers) from
both sides of the equation. To do so, we make use of
breakIt
function, in which we traverse
over the given equation(either left hand side or right hand side), and put the separated parts into an array.

Now, the idea is as follows. We treat the given equation as if we're bringing all the
x
's
on the left hand side and all the rest of the numbers on the right hand side as done below for an example.

x+5-3+x=6+x-2


x+x-x=6-2-5+3


Thus, every
x
in the left hand side of the given equation is treated as positive, while
that on the right hand side is treated as negative, in the current implementation.

Likewise, every number on the left hand side is treated as negative, while that on the right hand side is treated as positive. Thus, by doing so, we obtain all the
x
's
in the new lhslhs and
all the numbers in the new rhsrhs of
the original equation.

Further, in case of an
x
, we also need to find its corresponding coefficients in order
to evaluate the final effective coefficient of
x
on the left hand side. We also evaluate
the final effective number on the right hand side as well.

Now, in case of a unique solution, the ratio of the effective rhsrhs and lhslhs gives
the required result. In case of infinite solutions, both the effective lhslhs and rhsrhsturns
out to be zero e.g.
x+1=x+1
. In case of no solution, the coefficient of
x
(lhslhs)
turns out to be zero, but the effective number on the rhsrhs is
non-zero.

Java

public class Solution {
public String coeff(String x) {
if (x.length() > 1 && x.charAt(x.length() - 2) >= '0' && x.charAt(x.length() - 2) <= '9')
return x.replace("x", "");
return x.replace("x", "1");
}
public String solveEquation(String equation) {
String[] lr = equation.split("=");
int lhs = 0, rhs = 0;
for (String x: breakIt(lr[0])) {
if (x.indexOf("x") >= 0) {
lhs += Integer.parseInt(coeff(x));
} else
rhs -= Integer.parseInt(x);
}
for (String x: breakIt(lr[1])) {
if (x.indexOf("x") >= 0)
lhs -= Integer.parseInt(coeff(x));
else
rhs += Integer.parseInt(x);
}
if (lhs == 0) {
if (rhs == 0)
return "Infinite solutions";
else
return "No solution";
}
return "x=" + rhs / lhs;
}
public List < String > breakIt(String s) {
List < String > res = new ArrayList < > ();
String r = "";
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == '+' || s.charAt(i) == '-') {
if (r.length() > 0)
res.add(r);
r = "" + s.charAt(i);
} else
r += s.charAt(i);
}
res.add(r);
return res;
}
}


Complexity Analysis

Time complexity : O(n)O(n).
Generating cofficients and findinn $lhsandandrhswill
takewilltakeO(n)$$.

Space complexity : O(n)O(n).
ArrayList resres size
can grow upto nn.


Approach #2 Using regex for spliting [Accepted]

Algorithm

In the last approach, we made use of a new function
breakIt
to obtain the individual components
of either the left hand side or the right hand side. Instead of doing so, we can also make use of splitting based on
+
or
-
sign,
to obtain the individual elements. The rest of the process remains the same as in the last approach.

In order to do the splitting, we make use of an expression derived from regular expressions(regex). Simply speaking, regex is a functionality used to match a target string based on some given criteria. The ?=n quantifier, in regex, matches any string that is
followed by a specific string nn.
What it's saying is that the captured match must be followed by nn but
the nn itself
isn't captured.

By making use of this kind of expression in the
split
functionality, we make sure that
the partitions are obtained such that the
+
or
-
sign
remains along with the parts(numbers or coefficients) even after the splitting.

Java

public class Solution {
public String coeff(String x) {
if (x.length() > 1 && x.charAt(x.length() - 2) >= '0' && x.charAt(x.length() - 2) <= '9')
return x.replace("x", "");
return x.replace("x", "1");
}
public String solveEquation(String equation) {
String[] lr = equation.split("=");
int lhs = 0, rhs = 0;
for (String x: lr[0].split("(?=\\+)|(?=-)")) {
if (x.indexOf("x") >= 0) {

lhs += Integer.parseInt(coeff(x));
} else
rhs -= Integer.parseInt(x);
}
for (String x: lr[1].split("(?=\\+)|(?=-)")) {
if (x.indexOf("x") >= 0)
lhs -= Integer.parseInt(coeff(x));
else
rhs += Integer.parseInt(x);
}
if (lhs == 0) {
if (rhs == 0)
return "Infinite solutions";
else
return "No solution";
} else
return "x=" + rhs / lhs;
}
}


Complexity Analysis

Time complexity : O(n)O(n).
Generating coefficients and finding $lhsandandrhswill
takewilltakeO(n)$$.

Space complexity : O(n)O(n).
ArrayList resres size
can grow upto nn.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: