leetcode 640. Solve the Equation

来源:互联网 发布:mac php集成环境工具 编辑:程序博客网 时间:2024/06/05 11:07

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]+)*
shareimprove this question
 
 
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 

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
 
 
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
 
12 
Yet JavaScript does not know lookbehind. – Bergi May 29 '12 at 18:45

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
 





这道题有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 breakItfunction, 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.


原创粉丝点击