Write a function to find the longest common prefix string amongst an Array of strings.
If there is no common prefix, return an empty string ""
.
Example 1:
Input: strs = ["flower","flow","flight"] Output: "fl"
Example 2:
Input: strs = ["dog","racecar","car"] Output: "" Explanation: There is no common prefix among the input strings.
NOTE:
1 <= strs.length <= 200
0 <= strs[i].length <= 200
strs[i]
consists of only lower-case English letters.
This problem is popular in LeetCode, GeeksForGeeks (also here) A collection of hundreds of interview questions and solutions are available in our blog at Interview Question Solutions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.text.DateFormat; | |
import java.text.SimpleDateFormat; | |
import java.util.ArrayList; | |
import java.util.Arrays; | |
import java.util.Date; | |
import java.util.HashMap; | |
import java.util.List; | |
import java.util.Map; | |
/** | |
* Write a function to find the longest common prefix string amongst an array of | |
* strings. | |
*/ | |
/** | |
* Solution 1: | |
* 1)assume the first element of the array is the longest common prefix | |
* 1 a) if it is blank, return blank | |
* 2)compare the longest common prefix with the next element in array | |
* 2 a) if they don't have matching first character, return blank | |
* 2 b) if they have matching, first character, find the longer and shorter among those two elements | |
* and look for the chance of having the shorter element in longer element | |
* 2 c) if the whole shorter element is not found in longer element, iteratively eliminate the rightmost character | |
* of the shorter element till it's length is greater than 0 | |
* 3) repeat the process till we deal with all the elements of the array or blank is returned | |
* | |
* Complexity: O(n^2) - O(n) to iterate n elements of array and O(n) at worst to iteratively check the characters of shorter element against the character of longer elements | |
* | |
* NOTE: It's a good idea to consider the shortest string from the list as the common prefix rather than taking the first one | |
* because this will reduce the number of comparisons | |
* | |
* | |
* | |
* @author rbaral | |
* | |
*/ | |
public class LongestCommonPrefix { | |
public static void main(String[] args) { | |
boolean testEnabled = true; | |
if (testEnabled) { | |
performTest(); | |
} else { | |
DateFormat format = new SimpleDateFormat("YYYY-M-d:H:m:s:S"); | |
System.out.println(format.format(new Date())); | |
String strs[] = {"abca", "aba", "aaab"}; | |
System.out.println("output is:" + longestCommonPrefix(strs)); | |
//System.out.println("output is:" + longestCommonPrefix1(strs)); | |
System.out.println(format.format(new Date())); | |
} | |
} | |
public static String longestCommonPrefix1(String[] strs) { | |
if (strs == null || strs.length == 0) { | |
return ""; | |
} | |
if (strs.length == 1) { | |
return strs[0]; | |
} | |
String longPref = ""; | |
//lets assume that the longest prefix is the first string | |
longPref = strs[0]; | |
if (longPref.length() == 0)//if it was empty string | |
{ | |
return ""; | |
} | |
for (int i = 1; i < strs.length; i++) { | |
if (strs[i].length() == 0 || longPref.charAt(0) != strs[i].charAt(0))//if they dont have first char matching | |
{ | |
return ""; | |
} | |
if (longPref.length() > strs[i].length()) { | |
longPref = getCommonPrefix(longPref, strs[i]); | |
} else { | |
longPref = getCommonPrefix(strs[i], longPref); | |
} | |
} | |
return longPref; | |
} | |
public static String getCommonPrefix(String longString, String shortString) {//we assume first be at least same length as second param | |
String temp = ""; | |
int foundIndex = -1; | |
foundIndex = longString.indexOf(shortString); | |
if (foundIndex != 0) { | |
//repetitively eliminate the rightmost char of the shortest string and check for the common prefix, | |
//till a match is found or one is empty | |
temp = shortString; | |
while (temp.length() > 0 && foundIndex != 0) { | |
temp = temp.substring(0, temp.length() - 1); | |
foundIndex = longString.indexOf(temp); | |
} | |
if (foundIndex != 0)//if still didn't find anything in common | |
{ | |
return ""; | |
} else { | |
return temp; | |
} | |
} else { | |
return shortString; | |
} | |
} | |
/** | |
* finds the longest common prefix among the strings in the given string array | |
* @param s | |
* @return | |
*/ | |
public static String longestCommonPrefix(String[] s){ | |
//first lets find the shortest string among the strings in the array | |
int minLength = Integer.MAX_VALUE; | |
String prefix = ""; | |
for(String a:s){ | |
if(a.length()<minLength){ | |
minLength = a.length(); | |
prefix = a; | |
} | |
} | |
//for every successive elements in the array, we find the matching prefix | |
for(int i=0;i<s.length;i++){ | |
//what is the match between prefix and s[i] | |
if(prefix.equals(s[i])){//dont need to compare | |
continue; | |
} | |
//now compare the prefix so far and the string s[i] and get the new prefix that holds for s[i] also | |
int index = 0; | |
String newPrefix = ""; | |
while(index<prefix.length()){//repeat till the length of previous prefix or the non-matching index of chars in s[i] | |
if(prefix.charAt(index)==s[i].charAt(index)){ | |
newPrefix+=prefix.charAt(index); | |
index++; | |
continue; | |
}else{ | |
prefix = newPrefix; | |
break; | |
} | |
} | |
//check if we got just blank common prefixes,if so we dont need to compare with others just return blank | |
if(prefix.length()==0){ | |
return prefix; | |
} | |
} | |
return prefix; | |
} | |
public static void performTest() { | |
Map<String[], String> testCases = new HashMap<String[], String>(); | |
List<String> failedCases = new ArrayList<String>(); | |
String result = ""; | |
String[] a = new String[]{}; | |
testCases.put(a, ""); | |
a = new String[]{"ab", "a"}; | |
testCases.put(a, "a"); | |
a = new String[]{"abc", "d"}; | |
testCases.put(a, ""); | |
a = new String[]{"acb", "b", "", ""}; | |
testCases.put(a, ""); | |
a = new String[]{"bbcb", "c", "aca"}; | |
testCases.put(a, ""); | |
a = new String[]{"bbcb", "ba", "bed"}; | |
testCases.put(a, "b"); | |
a = new String[]{"abca", "aba", "aaab"}; | |
testCases.put(a, "a"); | |
for (String[] testCase : testCases.keySet()) { | |
result = longestCommonPrefix(testCase); | |
//result = longestCommonPrefix1(testCase); | |
if (!result.equals(testCases.get(testCase))) { | |
failedCases.add("Failed for:{" + Arrays.toString(testCase) + "} got:" + result + " expected:" + testCases.get(testCase)); | |
} | |
} | |
System.out.println("TEST RESULT, Passed:" + (testCases.size() - failedCases.size()) + " failed:" + failedCases.size()); | |
for (String failure : failedCases) { | |
System.err.println(failure); | |
} | |
} | |
} |
No comments:
Post a Comment