面试热题(比较版本号)

给你两个版本号 version1 和 version2 ,请你比较它们。

版本号由一个或多个修订号组成,各修订号由一个 '.' 连接。每个修订号由 多位数字 组成,可能包含 前导零 。每个版本号至少包含一个字符。修订号从左到右编号,下标从 0 开始,最左边的修订号下标为 0 ,下一个修订号下标为 1 ,以此类推。例如,2.5.33 和 0.1 都是有效的版本号。

比较版本号时,请按从左到右的顺序依次比较它们的修订号。比较修订号时,只需比较 忽略任何前导零后的整数值 。也就是说,修订号 1 和修订号 001 相等 。如果版本号没有指定某个下标处的修订号,则该修订号视为 0 。例如,版本 1.0 小于版本 1.1 ,因为它们下标为 0 的修订号相同,而下标为 1 的修订号分别为 0 和 1 ,0 < 1 。

返回规则如下:

  • 如果 version1 version2 返回 1
  • 如果 version1 version2 返回 -1
  • 除此之外返回 0

看到这个题我们应该想到利用正则表达式对字符串进行过滤,变为字符数组

然后遍历每一个字符数组对应位进行比大小,如果大于返回1,如果小于返回-1,相等则返回0

但是有两个困难:

  • 正则表达式不太会
  • 不清楚Integer.parseInt()的方法,不确定会不会帮助我们删掉所谓的前导0

 “001”-1

我们开始撸代码:

  String[] a1 = version1.split("\\.");
  String[] a2 = version2.split("\\.");
for(int n = 0; n < Math.max(a1.length, a2.length); n++){
            //长度不够位补0
            int i = (n < a1.length ? Integer.parseInt(a1[n]) : 0);
            int j = (n < a2.length ? Integer.parseInt(a2[n]) : 0);
            if(i < j) return -1;
            else if(i > j) return 1;
        }

 过了!!!(这种方法还是比较巧妙地,要学会位数补0的思想)

第二种方法双指针

其实双指针的话,原理和上面那种方法是一致的,就是按‘.’进行分离,逐一的比较大小

先给大家看一段未知名的错误代码:

public int compareVersion(String version1, String version2) {
      int i=0;
      int j=0;
      while(i<version1.length()||j<version2.length()){
          while(i<version1.length()&&version1.charAt(i)=='.'){
               i++;
          }
          int num1=version1.charAt(i);
           while(j<version2.length()&&version2.charAt(j)=='.'){
               j++;
          }
          int num2=version2.charAt(j);
          if(num1>num2){
              return 1;
          }else if(num1<num2){
              return -1;
          }
      }
      return 0;
    }

       这段代码的原本初心是想遇到0就跳过(处理前导0),然后没有考虑‘.’,后面知道考虑‘.’,但是无从下手的糟糕思路(这可能也是大多数人一开始的思路

我们进入正题讲解:

 while(i<version1.length()||j<version2.length()){
          //每次循环,清空,重新开始计数
          int num1=0;
          int num2=0;
}

//"012" (((0*10)+0)*10+1)*10+2=12
while(i<version1.length()&&version1.charAt(i)!='.'){
               num1=num1*10+version1.charAt(i)-'0';
               i++;
 }
           while(j<version2.length()&&version2.charAt(j)!='.'){
               num2=num2*10+version2.charAt(j)-'0';
               j++;
}

 

这样写完美的解决了前导0的问题,因为0*任何数都等于0,碰到‘.’则结束循环

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

       因为我们两次循环结束之后,i,j都是处于‘.’的位置上,所以我们要进行i++、j++,以到达下一个新数的开头

 过了!!!

源码如下:

    public int compareVersion(String version1, String version2) {
      int i=0;
      int j=0;
      while(i<version1.length()||j<version2.length()){
          int num1=0;
          int num2=0;
          while(i<version1.length()&&version1.charAt(i)!='.'){
               num1=num1*10+version1.charAt(i)-'0';
               i++;
          }
           while(j<version2.length()&&version2.charAt(j)!='.'){
               num2=num2*10+version2.charAt(j)-'0';
               j++;
          }
          if(num1>num2){
              return 1;
          }else if(num1<num2){
              return -1;
          }
          i++;
          j++;
      }
      return 0;
    }

猜你喜欢

转载自blog.csdn.net/dfdbb6b/article/details/132262346