[#0165]feat(leetcode): Init project, add C# solution, unit test and README
This commit is contained in:
144
problems/0165-compare-version-numbers/csharp/Program.cs
Normal file
144
problems/0165-compare-version-numbers/csharp/Program.cs
Normal file
@@ -0,0 +1,144 @@
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,9 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
Reference in New Issue
Block a user