[leetcode]Longest Common Prefix
目录:
- 总结
- 思路与实现
- 我自己的一些笔记,关于java基本知识
1. 总结
- 现在的习惯是,先考虑正确case,然后考虑边界条件
- 写注释
- leetcode代码提交方式:需要的是按照class Solution给的接口来实现它的一个成员函数。可以在main中调用该函数来测试。
- 写循环时,要考虑【跳出循环的条件】
2. 思路与实现
1> Write a function to find the longest common prefix string amongst an array of strings.
从字符串数组中寻找最长共同前缀字符串。输入:字符串数组strs[];输出:最长、共同前缀字符串commonPrefix。
e.g.
2> 选择strs[]中的一个作为commonPrefix,然后与其他str进行比较。那么选择哪个str作为初始时的commonPrefix呢?首先用了strs[0]。
这样会存在一个问题,当我们比较到strs[]中的abc时,会不得不将commonPrefix(abcefgh)截掉一大部分(efgh),这意味着(efgh)与前面的strs的比较都是无效的。
那么应该选择哪个str作为初始commonPrefix呢?
要求的输出:最长、共同前缀字符串,那么它必须被所有的str包含:它也是最短的str的子串。
so, 最短的str -> commonPrefix初值。
3> 现在有了用来比较的commonPrefix了,那就开始比较呗。开始我是这么循环strs[]比较的:
1 for (i < strs.length) { 2 for (j < commonPrefix.length()) { 3 //some statements 4 } 5 }
双重for循环,o(T) = o(最短str的长度 x strs[]数组长度)
1 public class Solution { 2 public String longestCommonPrefix(String[] strs) { 3 // 注意边界条件:输入为空 4 if(strs.length == 0) { 5 return ""; 6 } 7 8 String commonPrefix = new String(); 9 commonPrefix = strs[0]; 10 int minLeng = strs[0].length(); 11 int minLengIndex = 0; 12 // 将长度最小的str存到commonPrefix 13 for (int i = 1; i < strs.length; i++) { 14 if (minLeng < strs[i].length()) { 15 continue; 16 } else { 17 minLeng = strs[i].length(); 18 commonPrefix = strs[i]; 19 minLengIndex = i; 20 } 21 } 22 23 // 循环剩余str,与commonPrefix比较,共同前缀存到commonPrefix 24 for (int i = 0; i < strs.length; i++) { 25 if(i == minLengIndex) { 26 continue; 27 } 28 29 // 对每一个Str从首字符开始,取子串比较 30 for (int j = 0; j < commonPrefix.length(); j++) { 31 System.out.println(commonPrefix + ":" 32 + strs[i].substring(0, j + 1)); 33 if (commonPrefix.substring(0, j + 1).equals(strs[i].substring(0, j + 1))) { 34 // 若相同,向右移动一个字符,取前缀子串继续比较 35 continue; 36 } else { 37 // 若不同,截取相同前缀子串代替commonPrefix;跳出这个str,比较下一个str 38 if (j == 0) { 39 commonPrefix = commonPrefix.substring(0, 1); 40 } else { 41 commonPrefix = commonPrefix.substring(0, j); 42 } 43 break; 44 } 45 } 46 } 47 return commonPrefix; 48 } 49 }
然后,Time Limit Exceed.
4> 题目AC不了,事情当然还没完。如何化简这个双重循环呢?接下来我参考了这位的代码(点击看原文)。
上面已经分析了,commonPrefix一定是最短的str的子串,我们只需循环这个最短的str(也就是commonPrefix的初值),循环变量是其长度,与strs[]依次比较,不匹配,将commonPrefix末尾字符截掉(长度变短啦)。那么什么情况下跳出循环呢?
一是commonPrefix被完全截掉(长度为0,没有匹配的前缀子串);
二是已经循环遍历完strs[]。
notice!1. 循环变量;2. 跳出循环的条件
1 /** 2 * Longest Common Prefix 3 * Write a function to find the longest common prefix string amongst an array of strings. 4 * 2015/6/14 5 * */ 6 7 public class LongestCommonPrefix { 8 public static String longestCommonPrefix(String[] strs) { 9 // 注意边界条件:输入为空 10 if (strs.length == 0) { 11 return ""; 12 } 13 14 String commonPrefix = new String(); 15 commonPrefix = strs[0]; 16 int minLeng = strs[0].length(); 17 // 将长度最小的str存到commonPrefix 18 for (int i = 1; i < strs.length; i++) { 19 if (minLeng > strs[i].length()) { 20 minLeng = strs[i].length(); 21 commonPrefix = strs[i]; 22 } 23 } 24 25 int endIndex = commonPrefix.length(); 26 int i = 0; 27 // 跳出循环的条件:commonPrefix被完全截掉,或者循环遍完玩strs[] 28 while (endIndex > 0 && i < strs.length) { 29 if (commonPrefix.substring(0, endIndex).equals( 30 strs[i].substring(0, endIndex))) { 31 // 若匹配,则比较下一个str 32 i++; 33 } else { 34 // 不匹配,则commonPrefix截去末尾字符,继续比较同一个str 35 endIndex--; 36 } 37 } 38 39 // commonPrefix被完全截掉,没有匹配的前缀子串 40 if (endIndex == 0) { 41 return ""; 42 } 43 44 // 取子串,commonPrefix不是真的被截掉啦 45 return commonPrefix.substring(0, endIndex); 46 } 47 48 public static void main(String[] args) { 49 String[] strs = new String[] { "abac", "aba", "abc" }; 50 System.out.println("-->" + longestCommonPrefix(strs)); 51 } 52 }
o(T) = o(max(strs[]数组长度,最短str的长度))
Accepted.
3. 我自己的一些笔记,关于java基本知识
- main();类方法
- Java判断字符串是否相等
- 三元表达式