尋找最長公共前綴

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

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

給定一個string數組,尋找公共的最長前綴;code

假設給定數組 ab, ac, ad, 那麼最長公共前綴爲a排序

基本思路:leetcode

1. 切分出每一個字符串的全部前綴,好比abc的前綴爲, "", a, ab, abc; 字符串

2. 將這些前綴鏈接成一個新的前綴數組;對於給定的例子, 能夠獲得,["", a, ab, "", a, ac, "", a, ad]的前綴數組;string

3. 那麼公共的前綴的,其數量必然等於輸入字符數組的總和n;好比 "" 確定是一個公共前綴,那麼在前綴數組總, 必然包含n個 "";it

接下來的問題是怎麼找到最長的公共前綴;io

最簡單的方法先排序,而後依次掃描前綴, 並計數;直到找到一個計數少於n的前綴,那麼前一個就是最長公共前綴;function

但若是排過序了, 其實能夠用二分查找的方式更快的找到答案;下面是二分查找的代碼:

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)
}
相關文章
相關標籤/搜索