一天一大 leet(最长公共前缀)难度:简单 DAY-15

20200614

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-90B2HGtO-1592188388045)(http://qiniu.gaowenju.com/leecode/banner/20200615.jpg)]

题目(难度:简单):

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

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

示例

  1. 示例 1
输入: ["flower","flow","flight"]
输出: "fl"
  1. 示例 2
输入: ["dog","racecar","car"]
输出: ""
解释: 输入不存在公共前缀。

说明

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

抛砖引玉

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-z7ZTHR07-1592188388047)(http://qiniu.gaowenju.com/leecode/20200615.png)]

  1. 如果输入空数组则返回空
  2. 任取一个字符串长度假设为最大相同长度
  3. 循环字符串数组没别找到与这个长度前 n 未相同,求 n,
    • 求 n,截取前 n 位比较
    • 不相同则 n–,知道找到相同
/**
 * @param {string[]} strs
 * @return {string}
 */
var longestCommonPrefix = function (strs) {
  if (!strs.length) return ''
  let _resultNum = strs[0].length - 1
  for (let i = 1; i < strs.length; i++) {
    while (
      strs[i - 1].substring(0, _resultNum + 1) !==
      strs[i].substring(0, _resultNum + 1)
    ) {
      _resultNum--
    }
  }
  return strs[0].substring(0, _resultNum + 1) || ''
}

官方答案

横向扫描

  • 使用递归那每次比较出来的公共前缀与之后的字符串比较
  • 递归中,每个字符串的位置均需要比较
/**
 * @param {string[]} strs
 * @return {string}
 */
var longestCommonPrefix = function (strs) {
  if (strs == null || strs.length == 0) {
    return ''
  }
  var prefix = strs[0]
  var count = strs.length
  for (var i = 1; i < count; i++) {
    prefix = CommonPrefix(String(prefix), String(strs[i]))
    if (prefix.length == 0) {
      break
    }
  }
  return prefix

  function CommonPrefix(str1, str2) {
    var length = Math.min(str1.length, str2.length)
    var index = 0
    while (index < length && str1.charAt(index) == str2.charAt(index)) {
      index++
    }
    return str1.substring(0, index)
  }
}

纵向扫描

从前往后遍历所有字符串的每一列,比较相同列上的字符是否相同,

  • 如果相同则继续对下一列进行比较,
  • 如果不相同则当前列不再属于公共前缀,当前列之前的部分为最长公共前缀。
/**
 * @param {string[]} strs
 * @return {string}
 */
var longestCommonPrefix = function (strs) {
  if (strs == null || strs.length == 0) {
    return ''
  }
  var length = String(strs[0]).length
  var count = strs.length
  for (var i = 0; i < length; i++) {
    var c = strs[0].charAt(i)
    for (var j = 1; j < count; j++) {
      if (i == strs[j].length || strs[j].charAt(i) != c) {
        return strs[0].substring(0, i)
      }
    }
  }
  return strs[0]
}

其他解法

re 初始化为数组中第一个元素,逐个比较,当比较通过时返回 re,否则削去末位直至比较通过。

/**
 * @param {string[]} strs
 * @return {string}
 */
var longestCommonPrefix = function (strs) {
  var re = strs[0] ? strs[0] : ''
  for (var i = 1; i < strs.length; i++) {
    var regex = new RegExp('^' + re)
    while (!regex.test(strs[i]) && re.length) {
      re = re.slice(0, re.length - 1)
      regex = new RegExp('^' + re)
    }
  }
  return re
}

博客: 小书童博客(http://gaowenju.com/)

公号: 坑人的小书童
坑人的小书童

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值