【LeetCode】640. 求解方程

197 阅读3分钟

image.png

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第20天,点击查看活动详情

测试岗位也越来卷了,除了基本的功能测试外,还要有编程基础、脚本经验才脱颖而出。

怎么才能提高我们的编程能力呢,刷LeetCode是最佳的途径之一,话不多数,刷题走起~

一、题目描述:

  • 题目内容

    image.png

  • 题目示例

    image.png

  • 题目解析

    • 3 <= equation.length <= 1000
    • equation 只有一个 '='. 
    • 方程由绝对值在 [0, 100]  范围内且无任何前导零的整数和变量 'x' 组成。

二、思路分析:

我们拿到本题,题目要求对一元一次方程式字符串求出x的解,左边是变量右边是结果,那么对于没有解的情况是什么样的,我们继续审题:

  • 本题提供方程式是的运算只有➕和➖两种运算
  • 方程式只有一个x变量,一元一次方程组
  • 当方程式无解时,则结果返回No solution
  • 当方程式无限解时,则结果返回Infinite solutions

根据我们之前在学校对方式程的解法时,步骤大概分为如下几步:

  1. "="号左边的表达式,求出x变量的和以及数字和
  2. 同理求出"="右边的表达式,求出x变量的和以及数字和
  3. 将右边的x变量和移到"="号左边与x变量进行减法计算
  4. 将左边的数字值移到"="号右边,与数字值进行减法计算
  5. 则x值就等于右边值/x系数
  • 方法一:模拟求解

    • 模拟解方程的过程,重点就是要找的x变量系数和数字值
    • 需要使用变量 sign 来存储"="两边的x变量的系数的符号情况
    • 将expiation表达式将"-"进行替换"+-",然后将"="替换成"+=+",然后“+”划分
    • 最后将expiation表达式转换成k*x=c
    • 我们按照上述思路,使用python实现代码如下:
      class Solution(object):
      def solveEquation(self, equation):
          """
          :type equation: str
          :rtype: str
          """
          equation = equation.replace('-', '+-')
          equation = equation.replace('=', '+=+')
          words = equation.split('+')
          print(words)
          
          k, c, sign = 0, 0, 1  # equation ==> k*x = c
          for word in words:
              if word == '=':
                  sign = -1
                  continue
              if len(word) == 1:
                  if word == 'x':
                      k += sign * 1
                  elif word.isdigit():
                      c += -sign * int(word)
              elif word == '-x':
                  k += -sign * 1
              elif len(word) > 1:
                  if word[-1] == 'x':
                      k += sign * int(word[:-1]) if word[0] != '-' else -sign * int(word[1:-1])
                  elif word[-1].isdigit():
                      c += -sign * int(word) if word[0] != '-' else sign * int(word[1:])
          if k == 0:
              return "No solution" if c else "Infinite solutions"
          return "x="+str(c//k) if not (c % k) else "No solution"
      
  • 方法二:正则表达式

    本题中方程式求解的过程,也是存在字符串查找到问题,因此可以直接使用正则表达式来查找
    • 当方程式字符串中有x字符时,其系数是1,因此在查找前我们需要对系数为1时x变量添加为1。可以使用正则函数re.sub()方法查找x并替换成1x
    • 方程式中是以"="划分的,因此使用split("=")将方程式分解成左右两个字符串并存储在exp中
    • 使用for循环遍历exp列表,在查找左右两边的表达式的x变量和数字值时,我们也同样需要借助re.findall()方法查找
    • 根据正则规则 '([-+]?\d+)x',查找x变量值,并进行累计和计算,添加到K列表中
    • 根据正则规则 '([-+]?\d+)\b',查找数字值,并进行累计和计算,添加到b列表中
    • 左边x变量与右边x变量相减,则求出K
    • 右边数值与左边数值相减,则求出B
    • 当x变量系数K为0时,且B==0时,则方程式为无限解
    • 当x变量系数K为0时,且B!=0时,则方程式为无解
    • 当x变量系数K不为0时,则x等于-B/K
    • 根据正则表达式,代替解析字符串繁琐的查找,代码量确实可以减少很多,实现代码如下:
      class Solution(object):
          def solveEquation(self, equation):
              """
              :type equation: str
              :rtype: str
              """
              exp = re.sub(r'\bx','1x',equation).split('=')
              k,b=[],[]
              for ex in exp:
                  k.append(sum(int(kk) for kk in re.findall(r'([-+]?\d+)x',ex)))
                  b.append(sum(int(bb) for bb in re.findall(r'([-+]?\d+)\b',ex)))
              K=k[0]-k[1] # sub(*k)
              B=b[0]-b[1] # sub(*b)
              if K==0:
                  return "Infinite solutions" if B==0 else "No solution"
              return "x="+str(-B//K)
      

三、总结:

本题考察对字符串按照方程式的解法规则进行解析模拟,当字符串的解析过程比较繁琐时,我们可以时正则表达式替代,AC提交记录如下:

image.png

  • 时间复杂度:O(n),n为表达式的长度
  • 空间复杂度:O(n),遍历表达式时需要使用临时空间

以上是本期内容,欢迎大佬们点赞评论,下期见~~~