JSleetcode最长公共前缀题解分析
壹❀引
今天做的⼜是⼀道让我沮丧的题,思路有,但是代码逻辑最后还是没能正确理出来,题名为,题⽬如下:
编写⼀个函数来查字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 ""。
⽰例 1:
输⼊: ["flower","flow","flight"]
输出: "fl"
⽰例 2:
输⼊: ["dog","racecar","car"]
输出: ""
解释: 输⼊不存在公共前缀。
说明:
所有输⼊只包含⼩写字母 a-z 。
还是记录下我的思路,虽然没能成功做出来,但是思路很重要!
贰❀我的解题思路
题⽬⽰例其实说的很清楚了,给定⼀个包含多个字符串的数组,出这些字符公共前缀,注意是前缀,也就是说从第⼀位字符开始就要相同才符合条件。
我的思路是这样,⾸先将数组元素按字符长度由短到长排列(事实证明这步多此⼀举)。
strs.sort((a,b)=>{return a.length-b.length});
经过排序,⽐如⽰例1就会变成["flow","flower","flight"],为什么说多此⼀举,事实上完全会存在字符长度⼀样的情况,⽐如flower与flight就⼀样,排序的意义不⼤。
其实我是想让最短的在前⾯,作为⽐较的参照元素,这样for循环⽐较的时候 i 可以从1开始。
每次遍历我都会让strs[0]作为正则匹配标准,如果有不满⾜的,就让strs[0]的字符长度逐渐减少,⼀直⽐较完,通过这个来决定是返回 '' 或者是我们前⾯定义好的满⾜条件的正则字符。
// ⼤概的意思
var len = strs[0].length;
for (var i = 1; i < strs.length; i++) {
var regexp = new Regexp(strs[0].substr(0,len));
if(strs[1].test(regexp)){
// 巴拉巴拉...
};
len -- ;
};
当然上述程序只是⼤概表⽰了我的意思,因为最后我在处理字符⽐较这块,怎么都没理出来,还是没能成功做出来苍天啊
所以我还是选择看看答案,⽐较幸运的是,⽤户⼤佬给出的三种解决⽅案中,第三个实现与我思路类似,我先贴代码:
/**
* @param {string[]} strs
* @return {string}
*/
var longestCommonPrefix = function (strs) {
// 判断空数组情况,并直接将第⼀位元素作为参照物
var re = strs[0] ? strs[0] : '';
// 注意,这⾥遍历是从1开始,因为第⼀位被我们拿来当参照物了
for (var i = 1; i < strs.length; i++) {
// 注意这⾥的正则加了^,表⽰从字符开始位置开始匹配
var regex = new RegExp('^' + re);
// ⽐较其它字符看是否符合,若不符合让正则条件的字符递减
字符串长度的正确表示while (!st(strs[i]) && re.length) {
// 这⾥控制了字符递减
re = re.slice(0, re.length - 1);
// 递减后重新声明正则
regex = new RegExp('^' + re);
};
};
return re;
};
看了⼤佬的实现,瞬间有种⾃⼰的美好梦想被别⼈代替实现了的错觉....代码上我简单加了注释,思路确实与我相同,但是我对于代码的把控真的太差了。
⾸先,数组按字符长度排序没必要,这点前⾯解释了。其次,我本意让第0位作为正则匹配条件,但是我的实现为new
Regexp(strs[0].substr(0,len)),并没有加**脱字符**。表⽰⼀定要从字符起始位置开始匹配,不太明⽩这个符号的同学有兴趣可以阅读博主这篇⽂章。
那么如果不加,就算我实现了,会挂在['ll', 'hello']这样的例⼦上,因为没限制必须是起始位置,正则会认定hello也包含了ll。
我在实现上,没把控好的点就是怎么让正则test不符合条件时继续⽐较,以及如何控制strs[0]字符长度的递减(毕竟总不能⼀直递减),想了半天,看了他⼈实现,⼀句!st(strs[i]) && re.length让我瞬间清醒....
这⾥简单复习下slice⽅法,slice(start,stop)中的start与stop均为索引,⽐如:
[1,2,3].slice(1);// [2,3]
[1,2,3].slice(0,1)// [1]
slice⽅法与上篇博客提到的substring⽅法有点像,都是含头不含尾,即匹配结果的长度为stop-start,包含start但不包含stop。
OK,⼀些⼩细节解释清楚了,我们来说说这段循环嵌套究竟做了什么。还是["flower","flow","flight"]为例:
⼀开始,正则条件为flower,与flow⽐较,由于test为false,所以flower递减,此时正则条件变为flowe。
flowe与flow再次⽐较,结果还是不通过,再次递减正则条件变成flow。
终于flow与flow相同,由于不再满⾜while循环条件,跳出循环,此时外层for循环的i⾃增。
于是正则条件flow接着与flight⽐较,由于不满⾜,继续递减,变成flo,同理不满⾜再递减,最后变成了fl满⾜了条件,while再次跳出循
环,for也因为循环完毕,最后的re被递减成了fl,被成功返回。
⽽再以例⼦["dog","racecar","car"]来看,dog与racecar的⽐较过程中,由于始终不满⾜条件,re字段最终会被slice成 '',所以这点确实很巧妙。
从⼀开始取出第1位字符作为参照条件,后⾯始终维护它,要么递减过程中满⾜了条件,要么递减成 '' ,最后将它作为最终结果返回。这样的思路确实⽐较清晰太多太多了!
那么关于本题就说到这⾥了。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。