leetcode
leetcode 551 ~ 600
求解方程

求解方程

难度:

标签:

题目描述

代码结果

运行时间: 23 ms, 内存: 15.9 MB


/*
 * 思路:
 * 1. 将方程以'='分割成左右两部分。
 * 2. 使用Stream解析左右两部分,统计x的系数和常数项。
 * 3. 将右侧的x系数移到左侧,常数项移到右侧。
 * 4. 求解x的值。
 * 5. 处理特殊情况:无解、无穷解。
 */
 
import java.util.Arrays;
 
public class Solution {
    public String solveEquation(String equation) {
        String[] parts = equation.split("=");
        int[] left = parsePart(parts[0]);
        int[] right = parsePart(parts[1]);
 
        int xCoefficient = left[0] - right[0];
        int constant = right[1] - left[1];
 
        if (xCoefficient == 0) {
            if (constant == 0) {
                return "Infinite solutions";
            } else {
                return "No solution";
            }
        }
        return "x=" + (constant / xCoefficient);
    }
 
    private int[] parsePart(String part) {
        return Arrays.stream(part.split("(?=[+-])"))
            .mapToInt(this::parseTerm)
            .reduce(new int[2], (acc, cur) -> {
                if (cur == Integer.MAX_VALUE) acc[0] += 1;
                else if (cur == Integer.MIN_VALUE) acc[0] -= 1;
                else acc[1] += cur;
                return acc;
            }, (a, b) -> new int[]{a[0] + b[0], a[1] + b[1]});
    }
 
    private int parseTerm(String term) {
        if (term.equals("x") || term.equals("+x")) return Integer.MAX_VALUE;
        if (term.equals("-x")) return Integer.MIN_VALUE;
        if (term.contains("x")) return Integer.parseInt(term.replace("x", ""));
        return Integer.parseInt(term);
    }
}

解释

方法:

该题解的思路是将方程按 '=' 符号拆分成左右两部分,然后分别处理每一部分。对于每一部分,从左到右遍历,记录 'x' 的系数之和以及常数项之和。最后对比左右两部分 'x' 的系数是否相等,如果相等,再判断常数项之和是否相等,相等则有无穷多解,不等则无解;如果 'x' 的系数不等,则可以求出唯一解。

时间复杂度:

O(n)

空间复杂度:

O(1)

代码细节讲解

🦆
在解析方程的过程中,针对系数为1的x(例如单个'x'或'+x'),你是如何处理的?
在处理方程时,如果遇到单个的'x'或'+x',这意味着x前没有具体数字表示其系数,因此默认此时x的系数为1。在代码中,这通过检查变量`v`是否以'x'结尾且长度为1或者变量`v`除去最后的'x'后为空(适用于'+x'和'-x'的情况)来判断。如果符合这些条件,就将系数设置为1(对应的正负号由之前的符号决定)。
🦆
函数`f(s)`中的变量`v`在末尾是'x'时,为什么会检查`v`的长度,然后决定是否只用1作为系数?
在函数`f(s)`中,如果变量`v`的末尾是'x',这表示`v`是一个表示x的系数的字符串。检查`v`的长度是为了处理不同情况下的输入格式,例如'2x'、'+3x'、'-x'或仅仅是'x'。如果`v`的长度大于1,那么除去末尾的'x'后,剩下的部分将被转换为整数,这个整数就是x的系数。如果`v`的长度为1(即只有'x'),或者去除'x'后为空(如'+x'或'-x'),则默认x的系数为1。
🦆
为什么在处理字符串时首先给`s`加上一个'+'符号?这样做有什么特殊的目的吗?
在处理字符串`s`时,首先加上一个'+'符号是为了简化接下来的处理逻辑。这样做可以确保每个数字或变量前都明确地有一个符号(不管是正号'+'还是负号'-'),这使得在遍历字符串时,可以统一地处理每个数字或变量前的符号,而不需要在字符串开头特殊处理缺失符号的情况。
🦆
当左右两部分的x系数相等时,你是如何确定是返回'Infinite solutions'还是'No solution'的?
当方程的左右两部分中x的系数相等时,这意味着所有x项在方程两边相互抵消,因此方程简化为一个常数等式。此时,如果左右两边的常数项也相等(即`y1 == y2`),则方程有无限多解,即任何x的值都满足方程,因此返回'Infinite solutions'。如果常数项不相等(即`y1 != y2`),则方程无解,因为没有x的值能满足这样的不等式,因此返回'No solution'。

相关问题

分数加减运算

给定一个表示分数加减运算的字符串 expression ,你需要返回一个字符串形式的计算结果。 

这个结果应该是不可约分的分数,即最简分数。 如果最终结果是一个整数,例如 2,你需要将它转换成分数形式,其分母为 1。所以在上述例子中, 2 应该被转换为 2/1

 

示例 1:

输入: expression = "-1/2+1/2"
输出: "0/1"

 示例 2:

输入: expression = "-1/2+1/2+1/3"
输出: "1/3"

示例 3:

输入: expression = "1/3-1/2"
输出: "-1/6"

 

提示:

  • 输入和输出字符串只包含 '0' 到 '9' 的数字,以及 '/', '+' 和 '-'。 
  • 输入和输出分数格式均为 ±分子/分母。如果输入的第一个分数或者输出的分数是正数,则 '+' 会被省略掉。
  • 输入只包含合法的最简分数,每个分数的分子分母的范围是  [1,10]。 如果分母是1,意味着这个分数实际上是一个整数。
  • 输入的分数个数范围是 [1,10]。
  • 最终结果的分子与分母保证是 32 位整数范围内的有效整数。