Ruby's Louvre

每天学习一点点算法

导航

leetcode 14. Longest Common Prefix

取得第一个做样板,然后与第二个字符串比较,看它们是否有共同前缀,没有那么将前缀的缩短一点,从后面砍掉一个字符再比较,有了前缀就再与第三,第四个比较

function longestCommonPrefix(strs) {
      if (strs.length == 0) return "";
      var prefix = strs[0];
      for (var i = 1; i < strs.length; i++) {
        while (strs[i].indexOf(prefix) != 0) {
          prefix = prefix.substring(0, prefix.length - 1);
          if (!prefix) return "";
        }
      }
      return prefix;
}

垂直扫描法,也是拿第一个字符串做样板,然后取其第一个字符,与剩下的所有字符串的第一个字符来比较,没问题就开始 比较第二个字符

function longestCommonPrefix(strs) {
      if (!Object(strs).length) {
        return "";
      }
      var first = str[0]
      for (var i = 0; i < first.length; i++) {
        var c = first[i];
        for (var j = 1; j < strs.length; j++) {
          if (i == strs[j].length || strs[j][i] != c)
            return first.substring(0, i);
        }
      }
      return first
    }

分治法

function longestCommonPrefix(strs) {
      if (strs == null || strs.length == 0) return "";
      return helper(strs, 0, strs.length - 1);
    }

    function helper(strs, l, r) {
      if (l == r) {
        return strs[l];
      } else {
        var mid = (l + r) >> 1
        var lcpLeft = helper(strs, l, mid);
        var lcpRight = helper(strs, mid + 1, r);
        return commonPrefix(lcpLeft, lcpRight);
      }
    }

    function commonPrefix(left, right) {
      var min = Math.min(left.length, right.length);
      for (var i = 0; i < min; i++) {
        if (left.charAt(i) != right.charAt(i))
          return left.substring(0, i);
      }
      return left.substring(0, min);
    }

先求出最短的字符长度,然后通过二分法求与其他的共同前缀

function longestCommonPrefix(strs) {
      if (strs == null || strs.length == 0)
        return "";
      var minLen = Number.MAX_VALUE;//找到最短的字符串长度
      for (let str of strs) {
        minLen = Math.min(minLen, str.length);
      }

      var low = 1;
      var high = minLen;
      while (low <= high) {
        var middle = (low + high) >> 1;
        if (isCommonPrefix(strs, middle)) {
          low = middle + 1;
        } else {
          high = middle - 1;
        }

      }
      return strs[0].substring(0, (low + high) >> 1);
    }

    function isCommonPrefix(strs, len) {
      var str1 = strs[0].substring(0, len);
      for (var i = 1; i < strs.length; i++) {
        if (!strs[i].startsWith(str1))
          return false;
      }
      return true;
    }

使用前缀树

function Node(value) {
      this.value = value
      this.isEnd = false
      this.children = {}
      this.passCount = 0;
      this.endCount = 0
    }
    class Trie {
      constructor() {
        this.root = new Node(null)
      }
      insert(word) {

        var cur = this.root;
        for (var i = 0; i < word.length; i++) {
          var c = word[i];
          var node = cur.children[c];
          if (!node) {
            node = cur.children[c] = new Node(c)
          }

          cur = node;
          cur.passCount++ ////有N个字符串经过它
        }
        cur.endCount++; //这个字符串重复添加的次数
      }
      longestCommonPrefix(n) {
        var cur = this.root, lcp = '', wordsCount = 0
        while (true) {
          var count = 0
          var kids = cur.children;
          for (var i in kids) {
            if (kids.hasOwnProperty(i)) {
              count++
            }
          }
          //如果这父节点只有一个孩子,说明没有分叉
          if (count == 1) {
            cur = kids[i];
            //根节点的独生子的passCount,就是插入的字符串的总数量, 只计算一次
            if (!wordsCount) {
              wordsCount = cur.passCount
            }
            if (cur.passCount == wordsCount) {//由于是共同前缀,因此保证所有字符串都经过这节点
              lcp += cur.value
              continue //继续搜索下一个节点
            }
          }
          return lcp;
        }
        return lcp
      }
    }
    function longestCommonPrefix(words) {
      var trie = new Trie;
      for (let word of words) {
        if (word == '') {
          return ''
        }
        trie.insert(word);

      }
      return trie.longestCommonPrefix()
    }
    console.log(longestCommonPrefix(["flower", "flow", "flight"]))
    console.log(longestCommonPrefix(["aa", "a"]))
    console.log(longestCommonPrefix(["aaa", "aa", 'aac']))

posted on 2019-12-14 22:17  司徒正美  阅读(285)  评论(0编辑  收藏  举报