• LeetCode 0640.求解方程:过几天就看不懂了的迷惑性代码,但是是详解


    【LetMeFly】640.求解方程:过几天就看不懂了的迷惑性代码,但是是详解

    力扣题目链接:https://leetcode.cn/problems/solve-the-equation/

    求解一个给定的方程,将x以字符串 "x=#value" 的形式返回。该方程仅包含 '+''-' 操作,变量 x 和其对应系数。

    如果方程没有解,请返回 "No solution" 。如果方程有无限解,则返回 “Infinite solutions”

    如果方程中只有一个解,要保证返回值 'x' 是一个整数。

     

    示例 1:

    输入: equation = "x+5-3+x=6+x-2"
    输出: "x=2"
    

    示例 2:

    输入: equation = "x=x"
    输出: "Infinite solutions"
    

    示例 3:

    输入: equation = "2x=x"
    输出: "x=0"
    

     

     

    提示:

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

    方法一:模拟

    自认为这道题代码写得太具有迷惑性了,推荐一波官解。如果不嫌弃,也可以看一看我的思路:

    首先确定等号的位置,这样我们就可以得知左边的表达式和右边的表达式的范围了。

    对于某个表达式,我们求出其中 x x x的系数和常数分别为多少。

    那么具体怎么求呢?

    首先我们把表达式分割成一个一个的小单元“-2”、“+3”、“5”、“-x”、“-2x”、“x”、“3x”等,分割规则是:遇到下一个“加减号”或到表达式结尾。

    对于某个“小单元”,可以手写一个atoi函数求出这个小单元的值/ x x x的系数(如果最后一个字符是x就加到 x x x的系数上,否则就加到常数上)(如果最后一个字符是x,那么调用atoi时就把长度减少一位,不把x这个字符传递给atoi函数)

    那么怎么写atoi函数呢?

    首先要讨论传递到这个函数中的字符串有哪几种情况:

    • -2(来自-2-2x
    • +3(来自+3+3x
    • 5(来自55x
    • -(来自-x
    • ``````(来自x

    只要我们能处理好上述 5 5 5种情况,那么对于本题来说,就是一个完美的atoi函数。(不能使用自带的atoi,否则+-、``````都将被处理为 0 0 0

    最后回到初始问题,我们知道了左边 x x x的系数、左边的常数、右边 x x x的系数、右边的常数,如果“左边 x x x系数等于右边并且左边常数不等于右边”那么就“无解”( x + 1 = x + 2 x + 1 = x + 2 x+1=x+2),如果“左边 x x x系数等于右边并且左边并且左边常数等于右边”那么就“无数解”( x + 1 = x + 1 x + 1 = x + 1 x+1=x+1),否则方程的解为 x = 右边常数 − 左边常数 左边 x 系数 − 右边 x 系数 x=\frac{右边常数 - 左边常数}{左边x系数 - 右边x系数} x=左边x系数右边x系数右边常数左边常数

    • 时间复杂度 O ( n ) O(n) O(n),其中 n n n是字符串长度,每个字符最多遍历 3 3 3次(判断等号位置、确定下一个加减号的位置、确定某个“小单元”的值)
    • 空间复杂度 O ( 1 ) O(1) O(1)

    AC代码

    C++

    class Solution {
    private:
        int getEqualLocation(string& s) {
            for (int i = 0; i < s.size(); i++) {
                if (s[i] == '=')
                    return i;
            }
            return -1;  // Fake Return
        }
    
        int __LetMeFly_atoi(string& s, int left, int length) {
            if (length == 0) {
                return 1;
            }
            if (length == 1 && s[left] == '-') {
                return -1;
            }
            if (length == 1 && s[left] == '+') {
                return 1;
            }
            int k = 1;
            if (s[left] == '+')
                left++, length--;
            else if (s[left] == '-')
                left++, length--, k = -1;
            int ans = 0;
            while (length--) {
                ans *= 10;
                ans += s[left++] - '0';
            }
            return ans * k;
        }
    
        pair<int, int> getXandConst(string& s, int l, int r) {  // get [l, r) 's x and const
            pair<int, int> ans;
            int lastLoc = l;
            for (int nowLoc = l; nowLoc <= r; nowLoc++) {
                if (nowLoc != l && (nowLoc == r || s[nowLoc] == '+' || s[nowLoc] == '-')) {
                    // (lastLoc, nowLoc)
                    (s[nowLoc - 1] == 'x' ? ans.first : ans.second) += __LetMeFly_atoi(s, lastLoc, (s[nowLoc - 1] == 'x' ? nowLoc - 1 : nowLoc) - lastLoc);
                    lastLoc = nowLoc;
                }
            }
            return ans;
        }
    public:
        string solveEquation(string& equation) {
            int locEqual = getEqualLocation(equation);
            auto [leftX, leftConst] = getXandConst(equation, 0, locEqual);
            auto [rightX, rightConst] = getXandConst(equation, locEqual + 1, equation.size());
            if (leftX == rightX) {
                return leftConst == rightConst ? "Infinite solutions" : "No solution";
            }
            return "x=" + to_string((rightConst - leftConst) / (leftX - rightX));
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56

    同步发文于CSDN,原创不易,转载请附上原文链接哦~
    Tisfy:https://letmefly.blog.csdn.net/article/details/126262898

  • 相关阅读:
    Python——第6章 Numpy库的使用
    sql优化实操
    js 数组中相同类型的数据合并,并把相应的数据添加
    面渣逆袭:Redis连环五十二问,图文详解,这下面试稳了!
    Tomcat运行流程、Servlet运行原理以及常用API
    jsp简单实现新闻发布系统中用户注册确认和用户模拟登录功能的开发
    DEJA_VU3D - Cesium功能集 之 057-百度地图纠偏
    短视频社交|电影点播平台Springboot+vue+ElementUI前后端分离
    OpenCV(三十九):积分图像
    Vue源码阅读:createApp的过程(三)
  • 原文地址:https://blog.csdn.net/Tisfy/article/details/126262898