【C++算法打怪专栏】LeetCode 165. 比较版本号(双指针与字符串流法)

【C++算法打怪专栏】LeetCode 165. 比较版本号(双指针与字符串流法)

题目描述

给你两个版本号字符串 version1 和 version2 ,请你比较它们。版本号由修订号组成,修订号由点 . 分隔。如果 version1 > version2 返回 1,如果 version1 < version2 返回 -1,否则返回 0。


解法一:stringstream + getline 分割法(代码简洁)

💡 核心思路

利用 C++ 标准库中的 stringstream(字符串流)结合 getline 函数,按照指定分隔符 . 提取每一段修订号,再通过 stoi 转为整数进行比较。若某个版本号段数不足,流读取失败后默认将该段视为 0。

💻 代码实现

cpp 复制代码
#include <iostream>
#include <string>
#include <sstream>

using namespace std;

class Solution {
public:
    int compareVersion(string version1, string version2) {
        stringstream ss1(version1), ss2(version2);
        string s1, s2;

        // 只要其中一个版本号还有未读取的修订段,就继续比较
        while (ss1.good() || ss2.good()) {
            int v1 = 0, v2 = 0; // 默认缺省段为 0

            // 按照 '.' 提取修订号并转换为整数(自动忽略前导零)
            if (getline(ss1, s1, '.')) v1 = stoi(s1);
            if (getline(ss2, s2, '.')) v2 = stoi(s2);

            if (v1 < v2) return -1;
            if (v1 > v2) return 1;
        }

        return 0;
    }
};
  • 优点:逻辑清晰,代码优雅,省去手动处理字符转数字与前导零的繁琐细节。
  • 复杂度分析 :
    • 时间复杂度 :O(N+M)O(N + M)O(N+M),其中 NNN 和 MMM 分别为两个字符串的长度。
    • 空间复杂度 :O(N+M)O(N + M)O(N+M),使用了字符串流及临时字符串保存切割结果。

解法二:双指针原地方案(极致性能,0 额外空间)

💡 核心思路

定义两个指针分别指向 version1 和 version2 的起始位置,边遍历边用数字累加的方式解析出当前的修订号数值(遇 . 停止),比较完当前段后跳过 . 接着处理下一段。

💻 代码实现

cpp 复制代码
#include <iostream>
#include <string>

using namespace std;

class Solution {
public:
    int compareVersion(string version1, string version2) {
        int i = 0, j = 0;
        int n1 = version1.size(), n2 = version2.size();

        while (i < n1 || j < n2) {
            long long num1 = 0, num2 = 0;

            // 提取 version1 当前修订号数值
            while (i < n1 && version1[i] != '.') {
                num1 = num1 * 10 + (version1[i] - '0');
                i++;
            }
            i++; // 跳过 '.'

            // 提取 version2 当前修订号数值
            while (j < n2 && version2[j] != '.') {
                num2 = num2 * 10 + (version2[j] - '0');
                j++;
            }
            j++; // 跳过 '.'

            if (num1 < num2) return -1;
            if (num1 > num2) return 1;
        }

        return 0;
    }
};
  • 优点 :无需创建临时对象与切割子串,能达到 0 ms0\text{ ms}0 ms 执行用时与 O(1)O(1)O(1) 辅助空间开销。
  • 复杂度分析 :
    • 时间复杂度 :O(max⁡(N,M))O(\max(N, M))O(max(N,M)),线性双指针扫描一遍。
    • 空间复杂度 :O(1)O(1)O(1),仅需常数级别的双指针和计数变量。
相关推荐
微尘hjx4 小时前
【ByteTrack 04】多轨迹算法ByteTrack改进点
算法·yolo·目标检测·目标跟踪·bytetrack·ultralytics·车跟踪
dtq04245 小时前
C++小案例 - 日志实战
开发语言·c++
码匠许师傅6 小时前
【C++三方组件】Qt 概览:桌面 C++ 的事实标准与许可证三轨
开发语言·c++·qt
码匠许师傅7 小时前
【C++三方组件】POCO:跨平台系统编程全家桶
开发语言·c++
小蒋观天下8 小时前
雷击与浪涌防护:前端SPD选型、接地网误区,接地不当反而引入干扰
深度学习·算法·机器学习
WBluuue10 小时前
数据结构与算法:分块(一):块状数组、块状链表
数据结构·c++·算法·链表
圣保罗的大教堂10 小时前
leetcode 3619. 总价值可以被 K 整除的岛屿数目 中等
leetcode
澳鹏Appen11 小时前
澳鹏重磅发布ExamOCRBench:面向端到端试卷判分的多任务基准
算法·benchmark·基准评测
必须得开心呀11 小时前
字节序大小端科普
c++·程序人生