每日一道 LeetCode (5):最长公共前缀
前文合集
代码仓库
GitHub: https://github.com/meteor1993/LeetCode
Gitee: https://gitee.com/inwsy/LeetCode
题目:最长公共前缀
题目来源:https://leetcode-cn.com/problems/longest-common-prefix/
编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 ""。
示例 1:
输入: ["flower","flow","flight"]
输出: "fl"
示例 2:
输入: ["dog","racecar","car"]
输出: ""
解释: 输入不存在公共前缀。
说明:
所有输入只包含小写字母 a-z 。
解题思路 A :「暴力横向查找」
看到这道题,我又感觉我行了,先聊聊我没看答案之前的思路,这个思路我觉得是一个正常人,看到这道题应该有的,如果这个思路都没有,可能你比较适合学文科。
我的思路一般都很暴力,直接循环这个字符串数组,从第一个开始,挨个向后比较,比较两个字符串的每一个字符,遇到不一样的直接返回。
这思路够简单、暴力、直接吧,我想大家第一反应应该都能想得到这个方案。
接下来是代码时间:
public String longestCommonPrefix(String[] strs) {
if (strs.length == 0) return "";
String prefix = strs[0];
for (int i = 1; i < strs.length; i++) {
prefix = compareTwoStrs(prefix, strs[i]);
if (prefix.length() == 0) break;
}
return prefix;
}
// 获取两个字符串的公共前缀
private String compareTwoStrs(String str1, String str2) {
int length = Math.min(str1.length(), str2.length());
int index = 0;
while (index < length && str1.charAt(index) == str2.charAt(index)) {
index++;
}
return str1.substring(0, index);
}
我在 LeetCode 上运行了一下,直接得到这个结果,这个结果应该是我做 LeetCode 最好的结果了,竟然耗时小于 1ms ,难道我已经这么牛皮了么,我感觉自己飘了。
我满怀信心的打开了答案页,正准备写个回答装个 B 的时候,我傻眼了, NM ,这道题竟然有这么多种解法的啊,心态崩了啊。
忽然想到,刚才我的方案只是一个最简单的正向暴力破解的方案,但是我的解法耗时低于 1ms 啊,这么看来,我的解法还是可以的嘛。
解题思路 B :「暴力纵向查找」
我看到答案上把我上面的那种思路叫做「暴力横向查找」,然后大神们按照这个思路,又搞出来了「暴力纵向查找」。
图我就不画了,反正和上面的思路一致,就是把横向比较换成了纵向比较,然后一个接一个比一圈,直到最短的字符串长度结束,或者开始出现不一样的字符为止。
代码涨这个样子:
public String longestCommonPrefix_1(String[] strs) {
if (strs.length == 0) return "";
for (int i = 0; i < strs[0].length(); i++) {
for (int j = 1; j < strs.length; j++) {
if (i == strs[j].length() || strs[j].charAt(i) != strs[0].charAt(i)) {
return strs[0].substring(0, i);
}
}
}
return strs[0];
}
解题思路 C :「分治」
当我以为到这里就结束了的时候,我接着往下翻了翻答案,结果发现我自己还是图样图森破啊,我太小看了「学霸」和「大神」这两个词。
「分治」这个方案是先把字符串数组从中间切开,然后再按照「暴力横向查找」的方案分别取到切开后的两个数组的最长前缀,最后再从这两个前缀中取交集。
这种方案可以看做是「暴力横向查找」方案的一个变种方案,示意图如下:
public String longestCommonPrefix_2(String[] strs) {
if (strs.length == 0) {
return "";
} else {
return longestCommonPrefix(strs, 0, strs.length - 1);
}
}
public String longestCommonPrefix(String[] strs, int start, int end) {
if (start == end) {
return strs[start];
} else {
int mid = (end - start) / 2 + start;
String lcpLeft = longestCommonPrefix(strs, start, mid);
String lcpRight = longestCommonPrefix(strs, mid + 1, end);
return commonPrefix(lcpLeft, lcpRight);
}
}
public String commonPrefix(String lcpLeft, String lcpRight) {
int minLength = Math.min(lcpLeft.length(), lcpRight.length());
for (int i = 0; i < minLength; i++) {
if (lcpLeft.charAt(i) != lcpRight.charAt(i)) {
return lcpLeft.substring(0, i);
}
}
return lcpLeft.substring(0, minLength);
}
当然,这种方案还可以接着变种,把「暴力横向查找」替换成「暴力纵向查找」。
解题思路 D :「二分查找」
最后还有一种二分查找比较新奇,我觉得刷题少的人肯定想不到这种方案。
这种方案的思路是在字符串数组中,最长公共前缀的长度肯定不会超过字符串数组中的最短字符串的长度(如果超过了,也不会是最长公共前缀)。
首先找到最短的字符串长度 minLength ,然后随机找一个字符串判断这个 minLength 是否是最长公共前缀,如果不是则把这个 minLength 从中间劈开,接着判断前一半是不是公共前缀,如果是,则最长公共前缀一定大于等于这一半,如果不是,则最长公共前缀一定小于这一半,就这样逐渐缩小范围,直到找到为止。
这个我就不画图了,就是一个单纯的二分法不停的往下切,直到切中了为止。
public String longestCommonPrefix_3(String[] strs) {
if (strs.length == 0) return "";
// 先获取最小长度
int minLength = Integer.MAX_VALUE;
for (String str : strs) {
minLength = Math.min(minLength, str.length());
}
// 定义变量,开始二分法
int low = 0, high = minLength;
while (low < high) {
// 获取中间点
int mid = (high - low + 1) / 2 + low;
if (isCommonPrefix(strs, mid)) {
low = mid;
} else {
high = mid - 1;
}
}
return strs[0].substring(0, low);
}
public Boolean isCommonPrefix(String[] strs, int length) {
// 先获取前一半要比较的字符串
String str0 = strs[0].substring(0, length);
for (int i = 1; i < strs.length; i++) {
for (int j = 0; j < length; j++) {
// 按字符进行判断,如果有不一样的字符直接返回 false
if (str0.charAt(j) != strs[i].charAt(j)) {
return false;
}
}
}
return true;
}
从上面的结果看下来,好像是二分法的速度是最慢的,实际上这是由于测试的数据集的关系,测试所使用的的数据集可能都比较适合「暴力横向查找」这个方案。
每日一道 LeetCode (5):最长公共前缀的更多相关文章
- LeetCode:最长公共前缀【14】
LeetCode:最长公共前缀[14] 题目描述 编写一个函数来查找字符串数组中的最长公共前缀. 如果不存在公共前缀,返回空字符串 "". 示例 1: 输入: ["flo ...
- 【LeetCode】最长公共前缀【二分】
编写一个函数来查找字符串数组中的最长公共前缀. 如果不存在公共前缀,返回空字符串 "". 示例 1: 输入: ["flower","flow" ...
- LeetCode 14. 最长公共前缀(Longest Common Prefix)
14. 最长公共前缀 14. Longest Common Prefix 题目描述 编写一个函数来查找字符串数组中的最长公共前缀. 如果不存在公共前缀,返回空字符串 "". Lee ...
- Java实现 LeetCode 14 最长公共前缀
14. 最长公共前缀 编写一个函数来查找字符串数组中的最长公共前缀. 如果不存在公共前缀,返回空字符串 "". 示例 1: 输入: ["flower",&quo ...
- [LeetCode]14.最长公共前缀(Java)
原题地址: longest-common-prefix 题目描述: 编写一个函数来查找字符串数组中的最长公共前缀. 如果不存在公共前缀,返回空字符串 "". 示例 1: 输入:st ...
- python(leetcode)-14最长公共前缀
编写一个函数来查找字符串数组中的最长公共前缀. 如果不存在公共前缀,返回空字符串 "". 示例 1: 输入: ["flower","flow" ...
- LeetCode 7最长公共前缀
编写一个函数来查找字符串数组中的最长公共前缀. 如果不存在公共前缀,返回空字符串 "". 示例 1: 输入: ["flower","flow" ...
- leetcode 14 最长公共前缀
描述: 给个字符串vector,求最长公共前缀. 解决: 直接取第一个字符串作为最长公共前缀,将其每个字符遍历过一次.设最长字符实际为k,共n个元素,则复杂度O(nk) string longestC ...
- 领扣(LeetCode)最长公共前缀 个人题解
编写一个函数来查找字符串数组中的最长公共前缀. 如果不存在公共前缀,返回空字符串 "". 示例 1: 输入: ["flower","flow" ...
- LeetCode 14. 最长公共前缀(Longest Common Prefix)
题目描述 编写一个函数来查找字符串数组中的最长公共前缀. 如果不存在公共前缀,返回空字符串 "". 示例 1: 输入: ["flower","flow ...
随机推荐
- 洛谷 P1043 数字游戏 区间DP
题目描述 丁丁最近沉迷于一个数字游戏之中.这个游戏看似简单,但丁丁在研究了许多天之后却发觉原来在简单的规则下想要赢得这个游戏并不那么容易.游戏是这样的,在你面前有一圈整数(一共n个),你要按顺序将其分 ...
- ES2020的这些新功能令人期待
转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 原文出处:https://blog.bitsrc.io/es2020-has-been-finalized- ...
- scala 数据结构(七 ):集 Set
集是不重复元素的结合.集不保留顺序,默认是以哈希集实现 默认情况下,Scala 使用的是不可变集合,如果你想使用可变集合,需要引用 scala.collection.mutable.Set 包 1 集 ...
- java 面向对象(二十一):属性的赋值顺序
* ①默认初始化 * ②显式初始化/⑤在代码块中赋值 * ③构造器中初始化 * ④有了对象以后,可以通过"对象.属性"或"对象.方法"的方式,进行赋值 * * ...
- python 面向对象专题(九):特殊方法 (二)__get__、__set__、__delete__ 描述符(二)覆盖型与非覆盖型描述符对比
前言 根据是否定义__set__ 方法,描述符可分为两大类. 实现 __set__ 方法的描述符属于覆盖型描述符,因为虽然描述符是类属性,但是实现 __set__ 方法的话,会覆盖对实例属性的赋值操作 ...
- 数据可视化实例(十三): 发散型文本 (matplotlib,pandas)
偏差 (Deviation) https://datawhalechina.github.io/pms50/#/chapter11/chapter11 发散型文本 (Diverging Texts) ...
- 如何用HMS Nearby Service给自己的App添加近距离数据传输功能
当你给朋友发送手机资料时,过了很久进度条却动也不动:当你想发送大文件给同事时,仅一个文件就用光了你所有流量:当你跟朋友乘坐飞机时想一起玩游戏时,却因没有网络无奈放弃. 们生活中似乎经常能遇到这 ...
- java大数据最全课程学习笔记(3)--HDFS 简介及操作
目前CSDN,博客园,简书同步发表中,更多精彩欢迎访问我的gitee pages 目录 HDFS 简介及操作 HDFS概述 HDFS产出背景及定义 HDFS优缺点 HDFS组成架构 HDFS文件块大小 ...
- Python Ethical Hacking - TROJANS Analysis(4)
Adding Icons to Generated Executables Prepare a proper icon file. https://www.iconfinder.com/ Conver ...
- Python Ethical Hacking - WEB PENETRATION TESTING(4)
CRAWING SPIDER Goal -> Recursively list all links starting from a base URL. 1. Read page HTML. 2. ...