Files
coding-practice/problems/0165-compare-version-numbers/csharp/Program.cs

145 lines
3.4 KiB
C#

// 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<char> NextSegment(string version, ref int index)
{
if (index >= version.Length)
{
return ReadOnlySpan<char>.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<char> left, ReadOnlySpan<char> 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<char> TrimLeadingZeros(ReadOnlySpan<char> segment)
{
var index = 0;
while (index < segment.Length && segment[index] == '0')
{
index++;
}
return index == segment.Length ? ReadOnlySpan<char>.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);
}
}
}