我要提问
ARTICLE DETAIL

资讯详情

前沿编程新知与开发实战干货的深度解读。

每日一题:LeetCode 165:比较版本号

每日一题:LeetCode 165:比较版本号 一、题目要求给你两个版本号字符串version1 version2例如version1 1.2 version2 1.10版本号由.分隔成多个“修订号”。例如1.2 → [1, 2] 1.10 → [1, 10]比较时要从左到右逐段比较。如果某一段更大就能直接判断哪个版本更大。二、为什么不能直接比较字符串比如1.2 1.10不能用这种方式直接判断版本号大小。因为字符串比较是按字符比较不是按数值比较。我们真正想比较的是1 和 1 2 和 10所以应该先拆分1.2.split(.)得到[1, 2]而1.10.split(.)得到[1, 10]然后逐段转成数字比较。三、完整 JavaScript 代码var compareVersion function(version1, version2) { const v1 version1.split(.) const v2 version2.split(.) const len Math.max(v1.length, v2.length) for (let i 0; i len; i) { const n1 Number(v1[i] || 0) const n2 Number(v2[i] || 0) if (n1 n2) return 1 if (n1 n2) return -1 } return 0 }四、第一步split 拆版本号代码const v1 version1.split(.) const v2 version2.split(.)例如version1 1.2.3执行version1.split(.)得到[1, 2, 3]所以split(.)的作用就是按照.把字符串拆成数组。五、为什么要取最大长度代码const len Math.max(v1.length, v2.length)因为两个版本号的段数可能不同。比如version1 1.0 version2 1.0.0.0拆开后v1 [1, 0] v2 [1, 0, 0, 0]如果只遍历较短数组就比较不完整。所以要取Math.max(v1.length, v2.length)也就是两个数组中更长的那个长度。六、缺失的版本号为什么当 0题目规定如果某个版本号缺少某一段就把它看成 0。比如1.0 1.0.0实际上应该看成1.0.0 1.0.0所以这两个版本相等。代码里用了v1[i] || 0意思是如果v1[i]不存在就使用0例如const v1 [1, 0]当i 2时v1[2] // undefined于是v1[2] || 0结果就是0七、为什么要用 Number()代码const n1 Number(v1[i] || 0) const n2 Number(v2[i] || 0)因为split()得到的还是字符串。例如1.10.split(.)得到[1, 10]其中10还是字符串。所以我们要Number(10)得到10这样才能进行真正的数值比较。八、前导 0 怎么处理例如version1 1.01 version2 1.001题目要求忽略前导 0。所以01 001都应该看成1这也是为什么用Number()很方便。例如Number(01) // 1 Number(001) // 1所以前导 0 会自动被去掉。九、逐段比较核心代码if (n1 n2) return 1 if (n1 n2) return -1意思是如果当前这一段已经能分出大小就直接返回。比如version1 1.2 version2 1.10第一轮1 和 1相等继续。第二轮2 和 10因为2 10所以return -1后面不需要再比较了。十、为什么最后 return 0如果整个循环都没有返回1或者-1说明所有对应版本号都相等。例如version1 1.0 version2 1.0.0比较过程1 1 0 0 0 0所以最终return 0表示两个版本号相同。十一、完整执行示例例如version1 1.2 version2 1.10拆分v1 [1, 2] v2 [1, 10]最大长度len 2第一轮n1 1 n2 1相等继续。第二轮n1 2 n2 10因为2 10所以return -1十二、再看长度不同的情况version1 1.0 version2 1.0.0拆分v1 [1, 0] v2 [1, 0, 0]第三轮时v1[2] // undefined所以Number(v1[2] || 0) // 0而Number(v2[2] || 0) // 0两边还是一样。最终return 0十三、这道题的核心思路这道题其实可以压缩成四步1. 用 split(.) 拆版本号 2. 遍历两个数组的最大长度 3. 每一段用 Number() 转成数字 4. 从左到右逐段比较只要某一段出现n1 n2就返回1如果n1 n2就返回-1全部一样0十四、这道题主要考什么主要考三个点。1. 字符串处理split(.)把版本号拆开。2. 边界处理版本长度不一样时v1[i] || 0缺失部分按0处理。3. 类型转换Number()把字符串版本号转换成数字并自动处理前导 0。总结最终代码var compareVersion function(version1, version2) { const v1 version1.split(.) const v2 version2.split(.) const len Math.max(v1.length, v2.length) for (let i 0; i len; i) { const n1 Number(v1[i] || 0) const n2 Number(v2[i] || 0) if (n1 n2) return 1 if (n1 n2) return -1 } return 0 }总结先 split 拆版本号再从左到右逐段转成数字比较缺失部分补 0前导 0 用 Number 自动处理。
返回列表