// LeetCode 165: Compare Version Numbers // 難度: Medium // 日期: 2025-09-23 using System; public class Solution { // Two-pointer parser that compares segments without allocating intermediate arrays. public int CompareVersion(string version1, string version2) { var i = 0; var j = 0; while (i < version1.Length || j < version2.Length) { var segment1 = NextSegment(version1, ref i); var segment2 = NextSegment(version2, ref j); var comparison = CompareSegments(segment1, segment2); if (comparison != 0) { return comparison; } } return 0; } // Reads the next numeric segment (between dots) as a span and advances the current index. private static ReadOnlySpan NextSegment(string version, ref int index) { if (index >= version.Length) { return ReadOnlySpan.Empty; } var start = index; while (index < version.Length && version[index] != '.') { index++; } var segment = version.AsSpan(start, index - start); if (index < version.Length && version[index] == '.') { index++; } return segment; } // Compares two trimmed segments lexicographically to avoid integer overflow. private static int CompareSegments(ReadOnlySpan left, ReadOnlySpan right) { left = TrimLeadingZeros(left); right = TrimLeadingZeros(right); if (left.Length > right.Length) { return 1; } if (left.Length < right.Length) { return -1; } for (var i = 0; i < left.Length; i++) { if (left[i] > right[i]) { return 1; } if (left[i] < right[i]) { return -1; } } return 0; } private static ReadOnlySpan TrimLeadingZeros(ReadOnlySpan segment) { var index = 0; while (index < segment.Length && segment[index] == '0') { index++; } return index == segment.Length ? ReadOnlySpan.Empty : segment[index..]; } public int MyCompareVersion(string version1, string version2) { var v1 = version1.Split('.'); var v2 = version2.Split('.'); if (v1.Length >= v2.Length) { return CompareString(v1, v2); } return CompareString(v2, v1) * -1; } private static int CompareString(string[] longer, string[] shorter) { for (var i = 0; i < longer.Length; i++) { _ = int.TryParse(longer[i], out var num1); var num2 = i < shorter.Length && int.TryParse(shorter[i], out var parsed) ? parsed : 0; if (num1 > num2) { return 1; } if (num1 < num2) { return -1; } } return 0; } } public class Program { public static void Main(string[] args) { // optional: keep console app functional for manual verification if (args.Length == 2) { var solution = new Solution(); var result = solution.CompareVersion(args[0], args[1]); Console.WriteLine(result); } } }