最长公共前缀

188 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第10天,点击查看活动详情

题目

编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 ""。

示例 1:

输入:strs = ["flower","flow","flight"]
输出:"fl"
示例 2:

输入:strs = ["dog","racecar","car"]
输出:""
解释:输入不存在公共前缀。

题解

这题我们有很多种解法,可以构建字典树,也可以用暴力算法。我们这里就解释最简单的暴力算法破解,我们可以先确认一个前缀一个一个对比过去,一旦超过之后就直接退出了

AC Code

func longestCommonPrefix(strs []string) string {
    if len(strs) == 0 {
        return ""
    }
(1)    prefix := strs[0]
(2)    count := len(strs)
(3)    for i:=1; i<count; i++ {
(4)        prefix = lcp(prefix,strs[i])
(5)        if len(prefix) == 0 {
            break
        }
    }
    return prefix
}

func lcp(str1,str2 string) string{
(6)    length:=min(len(str1),len(str2))
(7)    index:=0
(8)    for index<length && str1[index]==str2[index]{
(9)        index++
    }
(10)    return str1[:index]
}

(11)func min(x,y int) int {
    if x>y {
        return y
    }
    return x
}
  • (1) 前缀先设置为数组中的第一个字符串
  • (2) 遍历的次数count为数组的长度
  • (3) 循环遍历这个数组即可
  • (4) 将这个 prefix 与一个一个的数组中的元素进行对比
  • (5) 如果是空的话,可以直接break
  • (6) 获取最小值
  • (7) 作为元素的下标
  • (8) 一直进行遍历,如果前缀一直相等,就一直找,直到不匹配,就break掉
  • (9) index++
  • (10) 返回相同的前缀结果
  • (11) 返回最小值

同样我们也可以构造前缀树来进行解题操作。

  • 构造字典树节点
type DictTreeNode struct {
   depth int
   next  []*DictTreeNode
}
  • new一个字典树节点
func newDictTreeNode() *DictTreeNode {
   return &DictTreeNode{next: make([]*DictTreeNode, 26)}
}
  • 返回根节点
type DictTree struct {
   root *DictTreeNode
}
  • 插入元素

为了减少空间,我们存入的是元素减去的'a'的值

func (t *DictTree) insert(str string) {
   cur := t.root
   for _, ch := range str {
      if cur.next[ch-'a'] == nil {
         cur.next[ch-'a'] = newDictTreeNode()
         cur.next[ch-'a'].depth = cur.depth + 1
      }
      cur = cur.next[ch-'a']
   }
}
  • 最前匹配
func (t *DictTree) prefixMatch(str string) int {
   cur := t.root
   for i := 0; i < len(str) && cur.next[str[i]-'a'] != nil; i++ {
      cur = cur.next[str[i]-'a']
   }
   return cur.depth
}