乘风破浪:LeetCode真题_014_Longest Common Prefix

一、前言

如何输出最长的共同前缀呢,在给定的字符串中,我们可以通过笨办法去遍历,直到其中某一个字符不相等了,这样就得到了最长的前缀。那么还有没有别的办法呢?

二、Longest Common Prefix

2.1 问题

2.2 分析与解决

    由问题我们可以知道,所有的字符都是小写的,这样我们不需要纠结这一部分,其次就是如何设计一种算法来遍历了。我们可以先计算出字符串的最小长度,然后作为循环的次数 ,之后来对比和查看。当然我们还有其他的方法,比如横向的两个两个进行求集,最终得到结果,或者纵向的按照我们上面的方法去比较。或者用分治法,二分搜索法,甚至采用树状结构搜索法。

    下面我们看看官网的答案:

    横向搜索法:

class Solution {
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;
}
}

    我们可以看到是非常巧妙的,通过第一个和第二个相比,刚开始使用indexOf()不成功会产生-1,如果成功了并且显示起始位置为0这样才算通过,其中每一次都是前缀去除一个字符来和原来的进行索引:prefix = prefix.substring(0, prefix.length() - 1);,然后将比较产生的prefix再和后面的继续比较,直至比较完毕得到想要的结果。

  纵向搜索法:

class Solution {
public String longestCommonPrefix(String[] strs) {
if (strs == null || strs.length == 0) return "";
for (int i = 0; i < strs[0].length() ; i++){
char c = strs[0].charAt(i);
for (int j = 1; j < strs.length; j ++) {
if (i == strs[j].length() || strs[j].charAt(i) != c)
return strs[0].substring(0, i);
}
}
return strs[0];
}
}

其实也是我们上面讲的,只不过没有比较最短长度而已。

分治法,思路也很简单,两两合并加快合并的效率:

class Solution {
public String longestCommonPrefix(String[] strs) {
if (strs == null || strs.length == 0) return "";
return longestCommonPrefix(strs, 0 , strs.length - 1);
} private String longestCommonPrefix(String[] strs, int l, int r) {
if (l == r) {
return strs[l];
}
else {
int mid = (l + r)/2;
String lcpLeft = longestCommonPrefix(strs, l , mid);
String lcpRight = longestCommonPrefix(strs, mid + 1,r);
return commonPrefix(lcpLeft, lcpRight);
}
} String commonPrefix(String left,String right) {
int min = Math.min(left.length(), right.length());
for (int i = 0; i < min; i++) {
if ( left.charAt(i) != right.charAt(i) )
return left.substring(0, i);
}
return left.substring(0, min);
}
}

相信看了代码和图片都能理解要表达的意思。

  二分查找法:

class Solution {
public String longestCommonPrefix(String[] strs) {
if (strs == null || strs.length == 0)
return "";
int minLen = Integer.MAX_VALUE;
for (String str : strs)
minLen = Math.min(minLen, str.length());
int low = 1;
int high = minLen;
while (low <= high) {
int middle = (low + high) / 2;
if (isCommonPrefix(strs, middle))
low = middle + 1;
else
high = middle - 1;
}
return strs[0].substring(0, (low + high) / 2);
} private boolean isCommonPrefix(String[] strs, int len){
String str1 = strs[0].substring(0,len);
for (int i = 1; i < strs.length; i++)
if (!strs[i].startsWith(str1))
return false;
return true;
}
}

     通过找到最小的字符串长度,然后对所有的字符串按照这个长度进行二分查找,不断的细化下去,看看在细化的过程中是否有共同的前缀,最终返回结果。

我们的算法:

public class Solution {
/**
* 题目大意
* 写一个函数找出一个字串所数组中的最长的公共前缀。
*
* 解题思路
* 第一步先找出长度最小的字符串,然后将这个字符串与其它的字符串相比找出最短的最公共前缀。
*/
public String longestCommonPrefix(String[] strs) {
if (strs == null) {
return null;
} if (strs.length == 0) {
return "";
} int min = Integer.MAX_VALUE; // 记录最短的字符串的长度 // 找短字符串的长度
for (String str : strs) { if (str == null) {
return null;
} if (min > str.length()) {
min = str.length();
}
} int i; // 记录最长前缀的字符数
boolean flag;
for (i = 0; i < min; i++) {
flag = true;
for (int j = 1; j < strs.length; j++) {
if (strs[0].charAt(i) != strs[j].charAt(i)) {
flag = false;
break;
}
} if (!flag) {
break;
}
} return strs[0].substring(0, i);
}
}

     从下往上分别是上面几种算法的耗时情况,可以看到在这种情况下使用分治法和二分查找算法和其他算法基本上性能差不多。

三、总结

在这里我们更加明白了算法的意义和多样性,对于同一个问题从不同的角度思考就有不同的解答方式,这点是算法的迷人之处。

乘风破浪:LeetCode真题_014_Longest Common Prefix的更多相关文章

  1. 【算法】LeetCode算法题-Longest Common Prefix

    这是悦乐书的第146次更新,第148篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第5题(顺位题号是14),给定一个随机的字符串数组,查找这些字符串元素的公共前缀字符串, ...

  2. 乘风破浪:LeetCode真题_017_Letter Combinations of a Phone Number

    乘风破浪:LeetCode真题_017_Letter Combinations of a Phone Number 一.前言 如何让两个或者多个集合中的随机挑选的元素结合到一起,并且得到所有的可能呢? ...

  3. 乘风破浪:LeetCode真题_041_First Missing Positive

    乘风破浪:LeetCode真题_041_First Missing Positive 一.前言 这次的题目之所以说是难,其实还是在于对于某些空间和时间的限制. 二.First Missing Posi ...

  4. 乘风破浪:LeetCode真题_040_Combination Sum II

    乘风破浪:LeetCode真题_040_Combination Sum II 一.前言 这次和上次的区别是元素不能重复使用了,这也简单,每一次去掉使用过的元素即可. 二.Combination Sum ...

  5. 乘风破浪:LeetCode真题_039_Combination Sum

    乘风破浪:LeetCode真题_039_Combination Sum 一.前言     这一道题又是集合上面的问题,可以重复使用数字,来求得几个数之和等于目标. 二.Combination Sum ...

  6. 乘风破浪:LeetCode真题_038_Count and Say

    乘风破浪:LeetCode真题_038_Count and Say 一.前言     这一道题目,很类似于小学的问题,但是如果硬是要将输入和结果产生数值上的联系就会产生混乱了,因此我们要打破思维定势. ...

  7. 乘风破浪:LeetCode真题_037_Sudoku Solver

    乘风破浪:LeetCode真题_037_Sudoku Solver 一.前言 这次我们对于上次的模型做一个扩展并求解. 二.Sudoku Solver 2.1 问题 2.2 分析与解决     这道题 ...

  8. 乘风破浪:LeetCode真题_036_Valid Sudoku

    乘风破浪:LeetCode真题_036_Valid Sudoku 一.前言 有的时候对于一些基础知识的掌握,对我们是至关重要的,比如ASCII重要字符的表示,比如一些基本类型的长度. 二.Valid ...

  9. 乘风破浪:LeetCode真题_035_Search Insert Position

    乘风破浪:LeetCode真题_035_Search Insert Position 一.前言 这次的问题比较简单,也没有限制时间复杂度,但是要注意一些细节上的问题. 二.Search Insert ...

随机推荐

  1. golang-开发配置

    环境变量配置 Windows GOROOT GOROOT = D:\ProgramDev\Go GOROOT GOROOT = D:\WorkSpace\goProjects GOBIN GOBIN ...

  2. Innosetup中在安装界面左下角添加超链接

    在程序的安装界面左下角加上超链接,如下图: 1. 新建一个标签,这里使用的控件是TNewStaticText ,完整的方法是 //该方法传入两个参数: //1. ParentForm:将这个URLLa ...

  3. To B服务想做移动化?腾讯云案例了解一下

    本文由 腾讯云助手团队 发布于 腾讯云云+社区 | 导语:腾讯云那么多资源和服务,就不能手机管理吗? 能. 当用户在使用To B服务时,往往会遇到各种各样的限制: 1.操作难度:涉及各种权限.多重验证 ...

  4. Code First配合Entity Framework Power Tools Beta 4使用

    基于现有数据库生成POCO数据类和数据库上下文需要借助Visual Studio一个扩展插件-- Entity Framework Power Tools(一个Code First反向工程工具).只要 ...

  5. Ubuntu 10.10, 11.04, 11.10这三个版本无法从优盘启动

    问题:Ubuntu 10.10, 11.04, 11.10这三个版本无法从优盘启动 解决:从U盘启动安装的时候,会卡住不动.搞定办法相当简单,修改syslinux/syslinuxfg文件:将defa ...

  6. python之virtualenv的简单使用

    什么是virtualenv? virtualenv可以创建独立Python开发环境,比如当前的全局开发环境是python3.6,现在我们有一个项目需要使用django1.3,另一个项目需要使用djan ...

  7. SQL SERVER学习1——数据库概念

    <SQL Server实例教程>(科学出版社) 数据库的基本概念 数据是载荷信息的物理符号,是数据库中存储的基本对象. 信息可以通过手势,眼神表达,但是表达信息的最佳方式还是数据. 数据有 ...

  8. 使用 csc.exe 编译C#代码

    csc.exe是C#的编译器,可以将C#代码编译为IL中间语言代码(exe.dll),然后再通过.net framework中的clr内的JIT(即时编译器)将中间语言代码编译为机器语言,然后再由机器 ...

  9. Class类文件结构简介

    Java跨平台的基础 各种不同平台的虚拟机与所有平台都统一使用的程序存储格式——字节码(ByteCode)是构成平台无关性的基石,也是语言无关性的基础.Java虚拟机不和包括Java在内的任何语言绑定 ...

  10. 对JDK、JRE和JVM的一些浅薄理解

    JDK:JDK(Java Development Kit),顾名思义是java程序的开发包,任何java程序想要运行都需要相应版本的JDK,可以到oracle下载(下载之后自带JRE和编译工具等,无需 ...