[leetcode]Longest Common Prefix

目录:

  1. 总结
  2. 思路与实现
  3. 我自己的一些笔记,关于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 }
View Code

然后,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 }
View Code

o(T) = o(max(strs[]数组长度,最短str的长度))

Accepted.

 


 

3. 我自己的一些笔记,关于java基本知识

  • main();类方法
  • Java判断字符串是否相等
  • 三元表达式

 

 

posted @ 2015-06-14 17:36  cardaminexhz  阅读(275)  评论(0编辑  收藏  举报