Find longest common prefix

https://leetcode.com/problems/longest-common-prefix/

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

Given an array of strings, find the longest common prefix;

Assuming a given array ab, ac, ad, then the longest common prefix is ​​a

The basic idea:

1. Divide all the prefixes of each string, for example, the prefix of abc is, "", a, ab, abc; 

2. Concatenate these prefixes into a new prefix array; for the given example, one can get, ["", a, ab, "", a, ac, "", a, ad], an array of prefixes;

3. Then the number of common prefixes must be equal to the sum n of the input character array; for example, "" must be a common prefix, then the total prefix array must contain n "";

The next question is how to find the longest common prefix;

The easiest way is to sort first, then scan the prefixes in turn, and count; until a prefix with a count less than n is found, then the previous one is the longest common prefix;

But if it is sorted, you can actually find the answer faster by binary search; the following is the code for binary search:

package main

import (
	"fmt"
	"sort"
)

func main() {
	strs := []string{"flower", "flow", "flight"}
	fmt.Printf("%s\n", longestCommonPrefix(strs))
}

func longestCommonPrefix(strs []string) string {
	if len(strs) == 0 {
		return ""
	}
	prefix := make([]string, 0, len(strs))

	for _, str := range strs {
		prefix = appendStrPrefix(prefix, str)
	}

	sort.Strings(prefix)

	return findCommonPrefix(prefix, len(strs))
}

func findCommonPrefix(pres []string, n int) string {
	i, j := 0, len(pres)-1

	for i <= j {
		m := (i + j) / 2

		c := countOfPreAt(pres, m)
		if c == n {
			i = m + 1
		} else {
			j = m - 1
		}
	}

	return pres[i-1]
}

func countOfPreAt(pres []string, p int) int {
	s := pres[p]

	i := p
	for i >= 0 && pres[i] == s {
		i--
	}

	j := p
	for j < len(pres) && pres[j] == s {
		j++
	}

	return (j - 1) - (i + 1) + 1
}

func appendStrPrefix(pre []string, str string) []string {
	for i := 0; i <= len(str); i++ {
		pre = appendMore(pre, str[:i])
	}
	return pre
}

func appendMore(strs []string, str string) []string {
	if len(strs)+1 == cap(strs) {
		tmp := make([]string, len(strs), 2*cap(strs))
		copy(tmp, strs)
		strs = tmp
	}
	return append(strs, str)
}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325776539&siteId=291194637