题目

14. 最长公共前缀

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

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

示例 1:

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

示例 2:

输入: ["dog","racecar","car"]
输出: ""
解释: 输入不存在公共前缀。

说明:

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

解答

解答一:两层for循环

误区1:刚开始考虑了先数组元素遍历,然后再元素(字符串)从头到尾比较,但实际上要先以第一个元素strs[0]为基准。

漏洞1:没有考虑strs元素为空字符串的情况,如[""],未考虑连续元素都相等的情况如["c","c"],结果这些在提交时都是要判断的。

个人思路:

1、若传入为空数组[]或空字符串[""]则直接返回空字符串;

2、取传入数组的第一个元素为基准字符串,并声明common数组,用于存放公共前缀;

3、第一层i循环(可以想像指针指向strs[0],且从strs[0][0]往str[0][1、2、3…]移动),第二层j循环(可以想像指针指向strs[1],且从strs[1]往str[2、3…]移动),即题中"flower"中的"f",与"flow"中的"f"相比较;

4、相同则j自增,即"flower"中的"f"继续与"flight"中的"f"比较;

5、若j循环未彻底完成,即说明当前的str[i]已经不是公共前缀了,就可以返回common了;若此次j循环彻底完成,则将当前的str[i],push进common;

6、外层的i循环结束后,若未触发过j循环内的return的话,类似["a","a","a"]["ab","abc","abcd"]等等情况的,直接返回strs[0],即str即可。

代码如下:(已在leetcode提交通过,执行用时104ms)

var longestCommonPrefix = function(strs) {
if (strs.length===0 ||strs[0].length===0){return "";}
var str=strs[0],
common=[];
for(let i=0,len1=str.length;i<len1;i++){
for(let j=1,len2=strs.length;j<len2;j++){
if(str[i]!==strs[j][i]){
return common.join("");
}
}
common.push(str[i]);
}return str;
};

两层循环示意图如下:

(GIF)

解答二:水平扫描法

参考平台提供题解,提供的第一种方法是“水平扫描法”:

仍然是先把数组中第一个元素str取出来,然后以这个元素为基准,

使用stringObject.indexOf(searchvalue,fromindex)方法查找,

查一下str是否在strs[i]索引为0的位置,

如果不在索引为0的位置,使用stringObject.substring(start,stop)删减字符串长度,

把str长度减1,再继续查,直到str长度减到0为止。

代码如下:(已在leetcode提交通过,执行用时100ms)

var longestCommonPrefix = function(strs) {
if (strs.length===0 ||strs[0].length===0){return "";}
var str=strs[0];
for (let i=1,len=strs.length;i<len;i++){
while(strs[i].indexOf(str)!==0) {
if (str.length === 0) {return "";}
str = str.substring(0, str.length - 1);
}
}return str;
}
 public String longestCommonPrefix(String[] strs) {
if (strs.length == 0) return "";
String prefix = strs[0];
for (int i = 1; i < strs.length; i++)
while (strs[i].indexOf(prefix) != 0) {
prefix = prefix.substring(0, prefix.length() - 1);
if (prefix.isEmpty()) return "";
}
return prefix;
}

平台提供 Java 实现代码

平台提供示意图如下:

解答三:水平扫描法(改良)

参考平台提供题解,水平扫描法有改良版,

不是取数组第一个元素,还是直接取该元素中的单独字符,类似本页中第一种方法,两个for循环,代码稍有区别。

首先第一层for循环(枚举首个字符串的所有字符),使用stringObject.charAt(index)方法获取数组第一个元素的第i个字符,赋值给c,

第二层for循环,从索引1开始遍历数组中所有剩余元素的对应i位置的字符,并与c比较,

如果该字符不等于c,或者压根没有该字符,直接使用stringObject.substring(start,stop)方法返回首个元素从索引0到i的拷贝,

若两层循环都正常运行过,未触发返回,则是类似["ab","abc","abcd"]["aa",aaa"","aaaaa"]这些情况,即第一个元素最短,且整体都符合条件,此时返回这个元素即可。

代码如下:(已在leetcode提交通过,执行用时92ms)

var longestCommonPrefix = function(strs) {
if (strs.length===0 ||strs[0].length===0){return "";}
for (let i=0,len1=strs[0].length;i<len1;i++){
let c=strs[0].charAt(i);
for (let j=1,len2=strs.length;j<len2;j++){
if(i===strs[j].length||strs[j].charAt(i)!==c){
return strs[0].substring(0,i);
}
}
}return strs[0];
}

解答四:分治

/**2019.03.11 01:40更新

*/

继续参考平台提供题解,算法三:分治

大致意思是把数组拆分成左右两部分,循环拆(递归?),直至最后一层的左右两部分都只有一个元素,

然后将这最后一层的两个元素进行比较,看是否有公共前缀,结果返回上一层,继续比较,最后到顶层;

仿照题解,我定义了三个函数,第一个是该题解要运行的函数longestCommonPrefix(),第二个是拆分函数divide(),第三个是比较函数compare();

longestCommonPrefix()返回divide()函数,并传入strs数组和该数组的索引起始、结束位置;

longestCommonPrefix()代码如下:

var longestCommonPrefix = function(strs) {
if (strs.length===0 ||strs[0].length===0){return "";}
return divide(strs,0,strs.length-1);
}

divide(strs,l,r)接收三个参数,strs:传入的数组;l(left):要拆分部分在strs中索引的开始位置;r(right):要拆分部分在strs中索引的结束位置;

在divide()中,首先判断传入参数的l和r,如果相等,即是开始位置与结束位置相同,该函数返回这个元素;

如果l不等于r,即数组还没拆到最后一层,把l和r求和后平分,向下取整,作为l和r的中点索引位置mid,然后中点前后两部分继续调用divide(),直至这两部分都返回一个元素;

divide()代码如下:

function divide(strs,l,r){
if(l===r){
return strs[l];
}else{
let mid=Math.floor((l+r)/2);
let leftPre=divide(strs,l,mid),
rightPre=divide(strs,mid+1,r);
return compare(leftPre,rightPre);
}
}

接着调用compare(),这个函数用来比较并找出这两个元素(字符串)的公共前缀,并将这个前缀返回至上一层和上层的另一部分返回的前缀继续比较;

依此类推,直到顶层,得出所有元素的最长公共前缀;

这里使用的方法和上个解答一致,两个,stringObject.substring(start,stop)stringObject.charAt(index)

compare()代码如下:

function compare(left,right){
let min=Math.min(left.length,right.length);
for(let i=0;i<min;i++){
if(left.charAt(i) !== right.charAt(i)){
return left.substring(0,i);
}
}return left.substring(0,min);
}

完整代码如下:(已在leetcode提交通过,执行用时108ms)

var longestCommonPrefix = function(strs) {
if (strs.length===0 ||strs[0].length===0){return "";}
return divide(strs,0,strs.length-1);
}
function divide(strs,l,r){
if(l===r){
return strs[l];
}else{
let mid=Math.floor((l+r)/2);
let leftPre=divide(strs,l,mid),
rightPre=divide(strs,mid+1,r);
return compare(leftPre,rightPre);
}
}
function compare(left,right){
let min=Math.min(left.length,right.length);
for(let i=0;i<min;i++){
if(left.charAt(i) !== right.charAt(i)){
return left.substring(0,i);
}
}return left.substring(0,min);
}

完整代码

平台提示意图如下:

说下自己碰到的坑,题解里面,这个"l"搞得像个阿拉伯数字"1",在这里浪费了不少时间,

【Leetcode】【简单】【14最长公共前缀】【JavaScript】的更多相关文章

  1. python刷LeetCode:14. 最长公共前缀

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

  2. 【LeetCode】14. 最长公共前缀

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

  3. 力扣(LeetCode) 14. 最长公共前缀

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

  4. leetcode.字符串.14最长公共前缀-Java

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

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

    14. 最长公共前缀 14. Longest Common Prefix 题目描述 编写一个函数来查找字符串数组中的最长公共前缀. 如果不存在公共前缀,返回空字符串 "". Lee ...

  6. Java实现 LeetCode 14 最长公共前缀

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

  7. 每日一道 LeetCode (5):最长公共前缀

    前文合集 每日一道 LeetCode 前文合集 代码仓库 GitHub: https://github.com/meteor1993/LeetCode Gitee: https://gitee.com ...

  8. 【leetcode算法-简单】14. 最长公共前缀

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

  9. LeetCode刷题-最长公共前缀(简单)

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

随机推荐

  1. (二)模板引擎之Velocity脚本基本的语法全

    velocity velocity三种reference     变量:对java对象的一种字符串化表示,返回值调用了java的toString()方法的结果.     方法:调用的是对象的某个方法. ...

  2. nyoj891(区间上的贪心)

    题目意思: 给一些闭区间,求最少须要多少点,使得每一个区间至少一个点. http://acm.nyist.net/JudgeOnline/problem.php?pid=891 例子输入 4 1 5 ...

  3. jQuery Validate 使用

    jQuery Validate 使用 <script src="js/b/js/jquery.validate.js"></script> <styl ...

  4. ICMP报文类型

     类型代码 类型描写叙述 0 响应应答(ECHO-REPLY) 3 不可到达 4 源抑制 5 重定向 8 响应请求(ECHO-REQUEST) 11 超时 12 參数失灵 13 时间戳请求 14 时间 ...

  5. 利用keepalive和timeout来推断死连接

    问题是这样出现的. 操作:client正在向服务端请求数据的时候,突然拔掉client的网线. 现象:client死等.服务端socket一直存在. 在网上搜索后,须要设置KEEPALIVE属性. 于 ...

  6. 未能加载文件或程序集“System.Web.Helpers, Version=2.0.0.0

    在本地终于用上了ASP.NET MVC4自带的认证功能,但放到生产服务器上就出问题了:打开注册页面没问题,但一点下注册按钮就报错了: 未能加载文件或程序集"System.Web.Helper ...

  7. Linux批量生成生成帐户脚本,随机密码

    此脚本应用于生产环境下生成帐户,也可生成成百上千个密码相同的帐户.脚本代码如下: 批量生成: #!/bin/bash for name in tom jerry joe jane do useradd ...

  8. Android WiFi开发教程(三)——WiFi热点数据传输

    在上一篇文章中介绍了WiFi的搜索和连接,如果你还没阅读过,建议先阅读上一篇Android WiFi开发教程(二)——WiFi的搜索和连接.本篇接着简单介绍手机上如何通过WiFi热点进行数据传输. 跟 ...

  9. 包含utf8字符的 pickle 转 json的大坑处理过程

    背景:希望将pickle转换为json,由于pickle里有utf8的字符,因此转换失败. 转换代码如下: ''' Convert a pkl file into json file ''' impo ...

  10. Centos6系列安装nginx

    设置ssh服务为开机启动 输入命令:chkconfig sshd on 即可.注:若是chkconfig sshd off则禁止SSH开机启动 设定账号为bizuser ,密码为123456 第一步: ...