[Leetcode] [14] Longest Common prefix analysis of two algorithms and the deep comparison of the underlying source code-java implementation

Source: Internet
Author: User

Q:

Write a function to find the longest common prefix string amongst an array of strings.

A:

The approximate meaning of this question is to give you a set of strings to find out which of the longest generic prefixes. It's not hard to find, but it's quick and easy. In fact, this is an easy topic, but let me associate with the "Data Structure and algorithm analysis" on a topic, the topic is this:

To a 8,900-word dictionary, from the middle to find similar words like ABC, BBC, ABB, there is only one letter of different words to classify, the worst algorithm, with everyone think of the traversal algorithm to classify time is more than 90 seconds, It only took 4 seconds to update to the fourth algorithm (and finally a 3-second method). He used the most critical change is to cut the word out of a letter and then exist in the TreeMap, if treemap some words on the inside of the size of +1, and finally find a size greater than 2 value, of course, I said before that there is a 3-second method is the use of HashMap.

The difference between HashMap and TreeMap I will be in my data structure and algorithm analysis review part of the talk. Please follow my blog if you are interested.

Let's think about how we can increase the speed in this way.

First we need to find out the range of prefixes, there are three options:

1. Find the smallest character and iterate through each letter as a prefix. O (N)

2, find the first character, traverse each letter as prefix O (1)

3. Find the common part of the first two characters and traverse the letter as prefix O (min (a.length,b.length).

For the range of prefixes we get we can get their number size.

Traverse the size to split the next string, such as [0,1],[0,2],[0,3] O (size*n)

Finally find out who size== the total number of strings in so many characters and her maximum value is the longest prefix we want. O (size)

So our last best time complexity situation should be O (size*n) and 0<size<=n,size as an integer, which means O (size*n) >o (n)




So let's look at the second method:

First, using the first two comparisons, the general prefix prefix is obtained. O (Prefix.length)

Use the generic prefix root for the next traversal to derive a generic prefix with prefix and assign a value to himself O (n)

Finally return to prefix

Her time complexity is O (prefix.length*n)

O (prefix.length*n) and O (Size*n) who are big who are small really bad compared. Let's analyze it.

If the size is determined using a third approach, then it should be equal to the first acquisition of prefix in the second method, i.e. o (prefix.length) =o (min (a.length,b.length).

For the second method, the prefix.length must be less than the first prefix.length. But for the first method, the first prefix.length equals the size after. The size of 1 and 2 in the first type is certainly large. Therefore, the second method is less complex in time after comparative analysis.

So we use the second method to calculate the code as follows:

public static void Main (string[] args) {string[] strs= {"AA", "a"}; System.out.println (Method (STRs));} private static String method (String[] STRs) {//TODO auto-generated method stubif (strs.length==0)            return "";        String prefix =strs[0];for (int i = 1;i<strs.length;i++) {//char Thisc = Prefix.charat (0); if (Prefix.length () >strs[ I].length ()) {prefix = prefix.substring (0, Strs[i].length ());} for (int j = 0;j< prefix.length (); j + +) {if (Prefix.charat (j)!=strs[i].charat (j)) {//ego unequal intercept prefixprefix = Prefix.substring (0, j);}} return prefix;}
Of course this is the original code, and then found to 5ms, I leetcode on the reference, modified into the following code:

public static void Main (string[] args) {string[] strs= {"AA", "a"}; System.out.println (Method (STRs));} private static String method (String[] STRs) {//TODO auto-generated method stubif (strs.length==0) return ""; String prefix =strs[0];for (int i = 1;i<strs.length;i++) {while (Strs[i].indexof (prefix)! = 0) {prefix = Prefix.substring (0,prefix.length ()-1);}} return prefix;}
This time consuming 1ms, the problem is string.indexof on one method, why is this method efficiency so high?

Let's look at the source code:

static int indexOf (char[] source, int sourceoffset, int sourcecount, char[] target, int targetoffset, int targe TCount, int fromIndex) {if (FromIndex >= sourcecount) {return (Targetcount = = 0? source        Count:-1);        } if (FromIndex < 0) {FromIndex = 0;        } if (Targetcount = = 0) {return fromIndex;        } char first = Target[targetoffset];        int max = Sourceoffset + (sourcecount-targetcount); for (int i = Sourceoffset + fromIndex; I <= max; i++) {/* look for first character. */if (SOURC            E[i]! = first) {while (++i <= max && source[i]! = first); }/* Found first character, now look at the rest of v2 * * IF (i <= max) {int J =                i + 1;                int end = j + targetCount-1;                   for (int k = Targetoffset + 1; J < end && Source[j]     = = Target[k];                J + +, k++);                if (j = = end) {/* Found whole string. */return I-sourceoffset;    }}} return-1; }

Default parameters:

Value, 0, value. Length,str. value, 0,str. value. length,0

We can see that the idea of this piece of code is to traverse to the first character and then the comparison, all the same returns index otherwise returns-1.

Let's try to modify the original code according to this idea.

if (strs.length==0)            return "";        String prefix =strs[0];for (int i = 1;i<strs.length;i++) {//if (Prefix.length () >strs[i].length ()) {//prefix = Prefix.substring (0, Strs[i].length ());//}int max= math.min (Prefix.length (), strs[i].length ()); int J = 0;for (;j< max &&prefix.charat (j) ==strs[i].charat (j); J + +) {}prefix = prefix.substring (0, j);} return prefix;
Finally I changed the source to this also have 4ms, and then I carefully contrast the source found that the problem should be String.charat () above, the code is as follows:

public char charAt (int index) {        if (Index < 0) | | (index >= value.length)) {            throw new stringindexoutofboundsexception (index);        }        return value[index];    }

There are two judgments that are very time-consuming, and we change to the following code
if (strs.length==0)            return "";        String prefix =strs[0];for (int i = 1;i<strs.length;i++) {//if (Prefix.length () >strs[i].length ()) {//prefix = Prefix.substring (0, Strs[i].length ());//}char[] str = Strs[i].tochararray (); int max= math.min (prefix.length (), str.length); int j = 0;for (;j< max&&prefix.charat (j) ==str[j];j++) {}prefix = prefix.substring (0, j);} return prefix;

becomes the 2ms, sure enough the problem is here, if we do not use the ToCharArray () method should be 1ms, which shows that our ideas and algorithms are not wrong, there are many things to pay attention to the bottom



[Leetcode] [14] Longest Common prefix analysis of two algorithms and the deep comparison of the underlying source code-java implementation

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.