14.最长公共前缀

题目

编写一个函数来查找字符串数组中的最长公共前缀。

如果不存在公共前缀,返回空字符串 ""

示例 1:

输入: ["flower","flow","flight"]
输出: "fl"

示例 2:

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

说明:

所有输入只包含小写字母 a-z

一. 双层循环

外层每次循环时,定义一个位置,内层每次循环时,根据外层提供的位置比较数组内的所有字符串此位置是否相等,如果有不等的,则结束循环,返回此位置之前的字符串。

js实现

/**
 * @param {string[]} strs
 * @return {string}
 */
var longestCommonPrefix = function(strs) {
  if (!strs.length) {
    return ''
  } else if (strs.length === 1) {
    return strs[0]
  }
  var i=0;
  while(true) {
    var char = strs[0][i]
    for (var j=1;j<strs.length;j++) {
      if (strs[j][i] !== char || char === undefined) {
        return strs[0].substring(0, i)
      }
    }
    i++
  }
};

复杂度分析

时间复杂度:O(mn)

空间复杂度:O(1)

测试结果

✔ Accepted
  ✔ 118/118 cases passed (72 ms)
  ✔ Your runtime beats 90.50 % of javascript submissions
  ✔ Your memory usage beats 43.13 % of javascript submissions (35 MB)

二. 二分查找法

首先,找出最短字符串的长度作为二分查找的区间,每次将查找区分对半分开:

  • 如果前面的区间不是所有串的公共前缀,那么,表明公共前缀比当前的字符串更短,将前面的区间二分再次比较
  • 如果前面的区间是所有串的公共前缀,那么,表明公共前缀比当前字符串更长,我们将后面的区间二分再次比较

js实现

/**
 * @param {string[]} strs
 * @return {string}
 */
var longestCommonPrefix = function(strs) {
  function isCommonPrefix(strs, len) {
    var str = strs[0].substr(0, len)
    for (var i=1;i<strs.length;i++) {
      if (str !== strs[i].substr(0, len)) {
        return false
      }
    }
    return true
  }

  if (!strs.length) {
    return ''
  }

  // 找出最小长度
  var minLen = strs[0].length
  for (var i=1;i<strs.length;i++) {
    var len = strs[i].length
    if (len < minLen) {
      minLen = len
    }
  }

  // 进行二分查找
  var left = 1
  var right = minLen
  while (left <= right) {
    var mid = (left + right) / 2 | 0
    if (isCommonPrefix(strs, mid)) {
      left = mid + 1
    } else {
      right = mid - 1
    }
  }

  return strs[0].substring(0, (left + right) / 2 | 0)
};

复杂度分析

时间复杂度:O(m*log(n))

空间复杂度:O(1)

测试结果

✔ Accepted
  ✔ 118/118 cases passed (64 ms)
  ✔ Your runtime beats 97.75 % of javascript submissions
  ✔ Your memory usage beats 82.95 % of javascript submissions (33.8 MB)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值