版本号比较问题

问题:

在某个项目中,每个版本都用版本号标记,由一个或多个修订号组成,修订号之间由点号.分隔。每个修订号可能有多位数字,并且可能会包含前导零。你需要根据两个版本号 version1version2,判断哪个版本更新,或者它们是否相同。

例如,2.5.330.1 都是有效的版本号。

当比较两个版本时,从左到右依次比较它们的修订号。忽略每个修订号的前导零,直接比较修订号对应的整数值。如果其中一个版本没有足够的修订号,缺失部分默认补为0

你需要根据以下规则返回比较结果:

  • 如果 version1 > version2,返回 1

  • 如果 version1 < version2,返回 -1

  • 如果两个版本相等,返回 0


测试样例

样例1:

输入:version1 = "0.1" , version2 = "1.1"
输出:-1

样例2:

输入:version1 = "1.0.1" , version2 = "1"
输出:1

样例3:

输入:version1 = "7.5.2.4" , version2 = "7.5.3"
输出:-1

样例4:

输入:version1 = "1.0" , version2 = "1.0.0"
输出:0

分析:

版本号是一个字符串,可以拆分成数组,转化为number类型的数组进行比较。

转化过程中,为了避免数组位数不一致,可以实现一个函数,进行补位,缺少的版本号补为0。比如:1.0 和 1.0.0,位数不一致[1,0] 和 [1,0,0],进行补位之后,期望的结果是 [1,0,0] 和 [1,0,0]。

解决:

1.补位+比较

getVersionList这个函数主要是进行补位,默认版本号最长四位,缺几位补几个0。

compareVersion去从左到右进行比较。

function getVersionList(version: string) {
  let versionList = version.split(".").map((item) => Number(item));
  const paddLength = 4 - versionList.length;
  if (paddLength < 1) return versionList;
  for (let index = 0; index < paddLength; index++) {
    versionList.push(0);
  }
  return versionList;
}

function compareVersion(versions1: number[], versions2: number[]) {
  for (let index = 0; index < versions1.length; index++) {
    const version1 = versions1[index];
    const version2 = versions2[index];
    if (version1 < version2) return -1;
    if (version1 > version2) return 1;
  }
  return 0;
}

function solution(version1: string, version2: string): number {
  const list1 = getVersionList(version1);
  const list2 = getVersionList(version2);
  return compareVersion(list1, list2);
}

function main() {
  // Add your test cases here
  console.log(solution("0.1", "1.1") === -1);
  console.log(solution("1.0.1", "1") === 1);
  console.log(solution("7.5.2.4", "7.5.3") === -1);
  console.log(solution("1.0", "1.0.0") === 0);
}

main();

2.单指针,双数组

上面的做法其实欠缺灵活性,版本号未必只有四位。其实 getVersionList 这一步的补位是不必要的。如果遇到取数undefined,当成0去处理就行。

单个指针,遍历范围为较长的那个数组。通过版本号比较(或者做相减操作判断)。

function getVersionList(version: string) {
  return version.split(".").map(Number);
}

function compareVersion(versions1: number[], versions2: number[]) {
  let index = 0;
  const longerIndex =  Math.max(versions1.length, versions2.length);
  while (index < longerIndex) {
    const version1 = versions1[index] || 0;
    const version2 = versions2[index] || 0;
    const compare = version1 - version2;
    if (compare !== 0) return compare > 0 ? 1 : -1;
    index++;
  }

  return 0;
}

function solution(version1: string, version2: string): number {
  const list1 = getVersionList(version1);
  const list2 = getVersionList(version2);
  return compareVersion(list1, list2);
}

function main() {
  // Add your test cases here
  console.log(solution("0.1", "1.1") === -1);
  console.log(solution("1.0.1", "1") === 1);
  console.log(solution("7.5.2.4", "7.5.3") === -1);
  console.log(solution("1.0", "1.0.0") === 0);
}

main();

3.单数组,双指针

指针分别指向两个数组的下标,比较相同时,下标后移继续比较

function getVersionList(version: string) {
  return version.split(".").map(Number);
}

function compareVersion(versions1: number[], versions2: number[]) {
  let firstIndex = 0;
  let secondIndex = 0;
  const maxLength = Math.max(versions1.length, versions2.length);
  while (firstIndex < maxLength && secondIndex < maxLength) {
    const version1 = versions1[firstIndex] || 0;
    const version2 = versions2[secondIndex] || 0;
    if (version1 !== version2) return version1 > version2 ? 1 : -1;
    firstIndex++;
    secondIndex++;
  }
  return 0;
}

function solution(version1: string, version2: string): number {
  const list1 = getVersionList(version1);
  const list2 = getVersionList(version2);
  return compareVersion(list1, list2);
}

function main() {
  // Add your test cases here
  console.log(solution("0.1", "1.1") === -1);
  console.log(solution("1.0.1", "1") === 1);
  console.log(solution("7.5.2.4", "7.5.3") === -1);
  console.log(solution("1.0", "1.0.0") === 0);
}

main();