寻找最长公共前缀

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

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

给定一个string数组,寻找公共的最长前缀;

假设给定数组 ab, ac, ad, 那么最长公共前缀为a

基本思路:

1. 切分出每个字符串的所有前缀,比如abc的前缀为, "", a, ab, abc; 

2. 将这些前缀连接成一个新的前缀数组;对于给定的例子, 可以得到,["", a, ab, "", a, ac, "", a, ad]的前缀数组;

3. 那么公共的前缀的,其数量必然等于输入字符数组的总和n;比如 "" 肯定是一个公共前缀,那么在前缀数组总, 必然包含n个 "";

接下来的问题是怎么找到最长的公共前缀;

最简单的方法先排序,然后依次扫描前缀, 并计数;直到找到一个计数少于n的前缀,那么前一个就是最长公共前缀;

但如果排过序了, 其实可以用二分查找的方式更快的找到答案;下面是二分查找的代码:

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)
}

 

转载于:https://my.oschina.net/u/922297/blog/700126

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值