壹 ❀ 引

今天做的又是一道让我沮丧的题,思路有,但是代码逻辑最后还是没能正确理出来,题名为最长公共前缀,题目如下:

编写一个函数来查找字符串数组中的最长公共前缀。

如果不存在公共前缀,返回空字符串 ""。

示例 1:

输入: ["flower","flow","flight"]
输出: "fl"

示例 2:

输入: ["dog","racecar","car"]
输出: ""

解释: 输入不存在公共前缀。

说明:

所有输入只包含小写字母 a-z 。

还是记录下我的思路,虽然没能成功做出来,但是思路很重要!

贰 ❀ 我的解题思路

题目示例其实说的很清楚了,给定一个包含多个字符串的数组,找出这些字符公共前缀,注意是前缀,也就是说从第一位字符开始就要相同才符合条件。

我的思路是这样,首先将数组元素按字符长度由短到长排列(事实证明这步多此一举)。

strs.sort((a,b)=>{return a.length-b.length});

经过排序,比如示例1就会变成["flow","flower","flight"],为什么说多此一举,事实上完全会存在字符长度一样的情况,比如flowerflight就一样,排序的意义不大。

其实我是想让最短的在前面,作为比较的参照元素,这样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 -- ;
};

当然上述程序只是大概表示了我的意思,因为最后我在处理字符比较这块,怎么都没理出来,还是没能成功做出来!!!苍天啊!!!

所以我还是选择看看答案,比较幸运的是,用户大佬rhinoc给出的三种解决方案中,第三个实现与我思路类似,我先贴代码:

/**
* @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 (!regex.test(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)),并没有加**脱字符**。表示一定要从字符起始位置开始匹配,不太明白这个符号的同学有兴趣可以阅读博主JS 正则表达式^$详解这篇文章。

那么如果不加,就算我实现了,会挂在['ll', 'hello']这样的例子上,因为没限制必须是起始位置,正则会认定hello也包含了ll

我在实现上,没把控好的点就是怎么让正则test不符合条件时继续比较,以及如何控制strs[0]字符长度的递减(毕竟总不能一直递减),想了半天,看了他人实现,一句!regex.test(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位字符作为参照条件,后面始终维护它,要么递减过程中满足了条件,要么递减成 '' ,最后将它作为最终结果返回。这样的思路确实比较清晰太多太多了!

那么关于本题就说到这里了。

JS leetcode 最长公共前缀 题解分析的更多相关文章

  1. leetcode 最长公共前缀

    编写一个函数来查找字符串数组中的最长公共前缀. 如果不存在公共前缀,返回空字符串"". 示例 1: 输入: ["flower","flow" ...

  2. LeetCode 最长公共前缀(探索字节跳动)

    题目描述 编写一个函数来查找字符串数组中的最长公共前缀. 如果不存在公共前缀,返回空字符串 "". 示例 1: 输入: ["flower","flow ...

  3. 领扣(LeetCode)最长公共前缀 个人题解

    编写一个函数来查找字符串数组中的最长公共前缀. 如果不存在公共前缀,返回空字符串 "". 示例 1: 输入: ["flower","flow" ...

  4. LeetCode:最长公共前缀【14】

    LeetCode:最长公共前缀[14] 题目描述 编写一个函数来查找字符串数组中的最长公共前缀. 如果不存在公共前缀,返回空字符串 "". 示例 1: 输入: ["flo ...

  5. 【Leetcode】【简单】【14最长公共前缀】【JavaScript】

    题目 14. 最长公共前缀 编写一个函数来查找字符串数组中的最长公共前缀. 如果不存在公共前缀,返回空字符串 "". 示例 1: 输入: ["flower",& ...

  6. 【LeetCode】最长公共前缀【二分】

    编写一个函数来查找字符串数组中的最长公共前缀. 如果不存在公共前缀,返回空字符串 "". 示例 1: 输入: ["flower","flow" ...

  7. 【LeetCode】14. Longest Common Prefix 最长公共前缀

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 个人公众号:负雪明烛 本文关键词:prefix, 公共前缀,题解,leetcode, 力扣 ...

  8. LeetCode 14 Longest Common Prefix(最长公共前缀)

    题目链接:https://leetcode.com/problems/longest-common-prefix/?tab=Description   Problem: 找出给定的string数组中最 ...

  9. 【LeetCode】Longest Common Prefix(最长公共前缀)

    这道题是LeetCode里的第14道题. 题目描述: 编写一个函数来查找字符串数组中的最长公共前缀. 如果不存在公共前缀,返回空字符串 "". 示例 1: 输入: ["f ...

  10. # Leetcode 14:Longest Common Prefix 最长公共前缀

    公众号:爱写bug Write a function to find the longest common prefix string amongst an array of strings. If ...

随机推荐

  1. 概率图模型 · 概率论基础 | 讲的非常好的 KL 散度博客

    知乎博客链接:https://zhuanlan.zhihu.com/p/425693597 感觉讲的非常好,谢谢善良的博主

  2. 项目使用 GlobalExceptionHandler 自定义异常 一

    博主原创,未经允许不得转载: 每个项目都有自己的一套异常类的定义.总结一下,项目中使用自定义异常比较好的封装. 1.定义项目中统一使用的异常类,用于捕获项目中的自定义异常等: package com. ...

  3. .net core 3.0 获取 IServiceProvider 实例

    .net core 3.0后,获取IServiceProvider需要绕点弯路 首先,新建一个类: public class MyServiceProviderFactory : IServicePr ...

  4. [转帖]浪潮PM8222-SHBA、RAID 2GB PM8204、RAID 4GB PM8204,阵列卡配置方法

    1.8222和8204对比 这几个型号的阵列卡都很相似,配置方法也基本一样 8204就是在8222上的基础上增加了缓存,可以通过下图对比 正面8204比8222多一个掉电保护接口 8204背面多了几个 ...

  5. [转帖]5 分钟学会写一个自己的 Prometheus Exporter

    https://cloud.tencent.com/developer/article/1520621学习一下怎么搭建呢.   去年底我写了一个阿里云云监控的 Prometheus Exporter, ...

  6. [转帖]oracle 审计日志清理

    https://www.cnblogs.com/bangchen/p/7268086.html   --进入审计日志目录: cd $ORACLE_BASE/admin/$ORACLE_SID/adum ...

  7. [转帖]Docker容器日志查看与清理(亲测有效)

    1. 问题 docker容器日志导致主机磁盘空间满了.docker logs -f container_name噼里啪啦一大堆,很占用空间,不用的日志可以清理掉了. 2. 解决方法 2.1 找出Doc ...

  8. [转帖]Linux系统下rpm命令使用详解

    简介 rpm命令是RPM软件包的管理工具.rpm原本是Red Hat Linux发行版专门用来管理Linux各项套件的程序,由于它遵循GPL规则且功能强大方便,因而广受欢迎.逐渐受到其他发行版的采用. ...

  9. [转帖]linux时间戳转换成时间指令_时间戳转换公式

    原文地址:http://wanping.blogbus.com/logs/28663569.html 1.时间戳转换为正常显示的时间格式 Freebsd 系统下: 转换命令为: date -r 111 ...

  10. [转帖]Linux设备与内存单位-扇区、块、段、页(sector、block、segment、page)

    每个概念是对不同的对象而言的,但它们有一定的联系 这些概念的分析背景是Linux下的内存页和磁盘结构 扇区 是硬盘等存储设备传送单位,大小一般为512B 块 是VFS和文件系统的传送单位(所以相关设备 ...