LeetCode刷题-最长公共前缀(简单)
题目描述
编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 ""。
示例 1:
输入: ["flower","flow","flight"]
输出: "fl"
示例 2:
输入: ["dog","racecar","car"]
输出: ""
解释: 输入不存在公共前缀。
说明:
所有输入只包含小写字母 a-z 。
方法一:水平扫描法
思路:
首先,我们将描述一种查找一组字符串的最长公共前缀LCP(S1..Sn)的简单方法。
我们将会用到这样的结论
LCP(S1. . .Sn) = LCP(LCP(LCP(S1,S2),S3). . .Sn)
算法
为了运用这种思想,算法要依次遍历字符串[S1...Sn],当遍历到第i个字符串的时候,找到最长公共前缀LCP(S1. . .Si)。当LCP(S1. . .S)是一个空串的时候,算法就结束了。否则,在执行了n次遍历之后,算法就会返回最终答案LCP(S1. . .Sn)。

代码实现
class Solution {
public String longestCommonPrefix(String[] strs) {
//如果字符串数组长度为0,返回空字符串""
if (strs.length == 0) return "";
//定义字符串数组第一个字符串为prefix
String prefix = strs[0];
for (int i = 1; i < strs.length; i++) {
//判断当前字符串strs[i]中是否有prefix(某个字符或某个字符串),
// 有的话就返回所在的下标(首次出现的位置),没有的话就返回-1
while (strs[i].indexOf(prefix) != 0) {
//prefix长度从后面减少一位
prefix = prefix.substring(0, prefix.length() - 1);
//如果不存在公共前缀,返回空字符串 ""
if (prefix.isEmpty()) return "";
}
}
return prefix;
}
}
方法二:xx扫描法
算法
想象数组的末尾有一个非常短的字符串,使用上述方法依旧会进行 S 次比较。优化这类情况的一种方法就是水平扫描。我们从前往后枚举字符串的每一列,先比较每个字符串相同列上的字符(即不同字符串相同下标的字符)然后再进行对下一列的比较。
代码实现
class Solution {
public String longestCommonPrefix(String[] strs) {
//如果字符串数组等于空或长度为0,返回空字符串""
if (strs == null || strs.length == 0) return "";
//这一层for循环遍历的是第一个字符串里的第 i 个字符串,后面的遍历都是与第一个字符串比对
for (int i = 0; i < strs[0].length() ; i++){
//把第一个字符串第i个字符赋给c
char c = strs[0].charAt(i);
//这一层for循环遍历的是第j字符串,并且取第 i 个字符串
for (int j = 1; j < strs.length; j ++) {
//如果i等于第j个字符串的长度 或 第j个字符串的第i个字符不等于c ,两者顺序不能颠倒
if (i == strs[j].length() || strs[j].charAt(i) != c)
//返回第一个字符串的0-i个字符
return strs[0].substring(0, i);
}
}
return strs[0];
}
}
算法三:分治思路
这个算法的思路来自于LCP操作的结合律。我们可以发现:
LCP(S1. . .Sn)= LCP(LCP(S1. . .SA),LCP(Sk + 1.Sn))
,其中LCP(S1. . .Sn)是字符串[S1..Sn]的最长公共前缀,1 < k < n。
算法
为了应用上述的结论,我们使用分治的技巧,将原问题LCP(S;…S;)分成两个子问题LCP(S;…Smid)与LCP(Smid + 1,S;),其中mid=i。我们用子问题的解1cpLeft 与1cpRi ght 构造原问题的解LCP(S;…S;)
。从头到尾挨个比较 lcpLeft 与 lcpRight 中的字符,直到不能再匹配为止。计算所得的 lcpLeft与 lcpRight最长公共前缀就是原问题的解 LCP(S;…S;)。

代码实现
public String longestCommonPrefix(String[] strs) {
//如果字符串数组等于空或长度为0,返回空字符串""
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;
//先从左半部分遍历,遍历的都是整个字符串,直到l等于r 返回最左边的字符串
String lcpLeft = longestCommonPrefix(strs, l, mid);
//遍历左半部分的右边,直到l等于r 返回左半部分右边的的字符串
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))
//substring(截取字符串)包括左边界,但却不包括右边界
return left.substring(0, i);
}
return left.substring(0, min);
}
方法四:二分查找法
思路
这个想法是应用二分查找法找到所有字符串的公共前缀的最大长度L。算法的查找区间是(0. . .minLen),其中minLen是输入数据中最短的字符串的长度,同时也是答案的最长可能长度。
每一次将查找区间一分为二,然后丢弃一定不包含最终答案的那一个。算法进行的过程中一共会出现两种可能情况:
- S[1. . .mid]不是所有串的公共前缀。这表明对于所有的 j > i S[ 1. .j ]也不是公共前缀,于是我们就可以丢弃后半个查找区间。
- S[1. . .mid]是所有串的公共前缀。这表示对于所有的 i < j S[ 1. .i ]都是可行的公共前缀,因为我们要找最长的公共前缀,所以我们可以把前半个查找区间丢弃。

代码实现
class Solution {
public String longestCommonPrefix(String[] strs) {
if (strs == null || strs.length == 0) {
return "";
}
//定义minLen初始值为Integer的最大值
int minLen = Integer.MAX_VALUE;
//遍历数组strs
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)) {
//在字符串是以str1为前缀开始的时候,low=middle+1是多遍历一个字符位置
low = middle + 1;
} else {
//字符串不是以str1为前缀开始的时候,high=midd-1,是少遍历一个字符位置
high = middle - 1;
}
}
//返回的是 截取第一个字符串0到mid字符串
return strs[0].substring(0, (low + high) / 2);
}
private boolean isCommonPrefix(String[] strs, int len){
//截取第一个字符串的前len个字符
String str1 = strs[0].substring(0,len);
for (int i = 1; i < strs.length; i++) {
//startsWith() 方法用于检测字符串是否以str1为前缀开始,如果不是直接return false
if (!strs[i].startsWith(str1)) {
return false;
}
}
return true;
}
}
LeetCode刷题-最长公共前缀(简单)的更多相关文章
- 每日一道 LeetCode (5):最长公共前缀
前文合集 每日一道 LeetCode 前文合集 代码仓库 GitHub: https://github.com/meteor1993/LeetCode Gitee: https://gitee.com ...
- 【leetcode 简单】第五题 最长公共前缀
编写一个函数来查找字符串数组中的最长公共前缀. 如果不存在公共前缀,返回空字符串 "". 示例 1: 输入: ["flower","flow" ...
- python刷LeetCode:14. 最长公共前缀
难度等级:简单 题目描述: 编写一个函数来查找字符串数组中的最长公共前缀. 如果不存在公共前缀,返回空字符串 "". 示例 1: 输入: ["flower",& ...
- 【LeetCode】14. 最长公共前缀
题目 编写一个函数来查找字符串数组中的最长公共前缀.如果不存在公共前缀,返回空字符串 "". 示例 1:输入: ["flower","flow&quo ...
- 力扣(LeetCode) 14. 最长公共前缀
编写一个函数来查找字符串数组中的最长公共前缀. 如果不存在公共前缀,返回空字符串 "". 示例 1: 输入: ["flower","flow" ...
- leetcode.字符串.14最长公共前缀-Java
1. 具体题目 编写一个函数来查找字符串数组中的最长公共前缀.如果不存在公共前缀,返回空字符串 "". 示例 1: 输入: ["flower","fl ...
- leetcode刷题--两数之和(简单)
一.序言 第一次刷leetcode的题,之前从来没有刷题然后去面试的概念,直到临近秋招,或许是秋招结束的时候才有这个意识,原来面试是需要刷题的,面试问的问题都是千篇一律的,只要刷够了题就差不多了,当然 ...
- 【LeetCode 14】最长公共前缀
题目链接 [题解] 二分最长前缀的长度. 然后暴力把第2..n个字符串和第1个字符串的前mid个字符匹配. 还有一种比较厉害的算法. 把这n个字符串加入到字典树当中去. 然后根节点到第一个有分支的节点 ...
- LeetCode刷题--有效的括号(简单)
题目描述 给定一个只包括 ' ( ' , ' ) ', ' { ' , ' } ' , ' [ ' , ' ] ' 的字符串,判断字符串是否有效.有效字符串需满足: 左括号必须用相同类型的右括号闭 ...
随机推荐
- 简单了解一下K8S,并搭建自己的集群
距离上次更新已经有一个月了,主要是最近工作上的变动有点频繁,现在才暂时稳定下来.这篇博客的本意是带大家从零开始搭建K8S集群的.但是我后面一想,如果是我看了这篇文章,会收获什么?就是跟着步骤一步一走吗 ...
- java开发中常用的Liunx操作命令
查看所有端口的占用情况 netstat -nultp 其中State值为LISTEN则表示已经被占用 查看某个端口的占用情况: netstat -anp |grep 端口号 在liunx中启动tomc ...
- Python3 函数进阶2
目录 迭代器 可迭代对象 迭代器对象 总结和补充 列表推导式 字典生成式 zip()函数 递归 迭代器 迭代器是访问容器类数据类型元素的一种方式 迭代器是一个可以记住遍历的位置的对象 迭代器对象从容器 ...
- Java类中static的用法
关于Java中static的使用有以下四种情况: 1.静态成员变量 被static修饰的成员变量,叫静态成员变量或类变量:没有被static修饰的变量,叫实例变量. 两者的区别是: ...
- android开发检测用户是否使用了虚拟定位
在应用开发中,如果有签到打卡之类的功能,你是否会遇到检测用户是否使用了虚拟定位软件来进行打卡?如果有,那么请仔细阅读这篇文章.该文章会带你认识什么是虚拟定位.什么是应用分身,以及如何通过代码来检测用户 ...
- 千呼万唤始出来——uFUN开发板2.0开箱评测
前言 今年3月,我参与了面包板社区组织的第一批uFUN开发板评测活动,并有幸能获得试用机会,那是我第一次了解到uFUN这个项目及背后的故事,4月份,uFUN 2.0版本来了,收到了张工送的一块样板,后 ...
- Jenkins工程中SQL语句执行的方法
前言 网上很多jenkins工程中基于shell或批处理方式调用sql文件执行sql命令的方式,大部分都是需要基于sql文件来完成的,因此在sql语句发生变化时需要去jenkins服务端修改对应的sq ...
- 智能家居手势识别,只需百度AI即可搞定
上次我尝试做了一个给眼镜加特效,针对的是静态图像,具体文章参考 https://ai.baidu.com/forum/topic/show/942890 . 这次我尝试在视频中加眼镜特效,并且加上手势 ...
- 2018 经典的CVPR 关于ImageCaptioning论文
1. SemStyle: Learning to Generate Stylised Image Captions using Unaligned Text(2018 CVPR) 主要研 ...
- 面试连环炮系列(六):Dubbo应用为什么要部署Zookeeper
Dubbo应用为什么要部署Zookeeper? Zookeeper用来注册和发现服务,简单说就是提供端注册接口信息到Zookeeper,调用端在Zookeeper上查找接口对应的服务IP和端口.由于Z ...