每日算法-4 最长公共前缀

问题:

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

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

示例 1:

输入: [“flower”,“flow”,“flight”]
输出: “fl”

示例 2:

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

说明:

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-common-prefix

解法:

一、纵向扫描法

纵向扫描时,从前往后遍历所有字符串的每一列,比较相同列上的字符是否相同,如果相同则继续对下一列进行比较,如果不相同则当前列不再属于公共前缀,当前列之前的部分为最长公共前缀。

每日算法-4 最长公共前缀_第1张图片



class Solution {

    /**
     * @param String[] $strs
     * @return String
     */
    function longestCommonPrefix($strs) {
        $publicCommonStr = '';
        $i = 0;
        while (true) {
            if (!isset($strs[0][$i])) {
                return $publicCommonStr;
            }
            for ($strsPos = 1; $strsPos < count($strs); $strsPos++) {
                //如果第一个字符串的i位字符不一致的话,即不再存在共用字符串,返回结果
                if ($strs[0][$i] !== $strs[$strsPos][$i]) {
                    return $publicCommonStr;
                }
            }
            //如果是共用的,那么拼接
            $publicCommonStr .= $strs[0][$i];
            $i++;
        }
    }
}

每日算法-4 最长公共前缀_第2张图片


二、二分查找法

最长公共前缀的长度不会超过字符串数组中的最短字符串的长度。用minLength表示字符串数组中的最短字符串的长度,则可以在[0,minLength]的范围内通过二分查找得到最长公共前缀的长度。每次取查找范围的中间值 mid,判断每个字符串的长度为mid的前缀是否相同,如果相同则最长公共前缀的长度一定大于或等于mid,如果不相同则最长公共前缀的长度一定小于mid,通过上述方式将查找范围缩小一半,直到得到最长公共前缀的长度。

每日算法-4 最长公共前缀_第3张图片



class Solution
{

    /**
     * @param String[] $strs
     * @return String
     */
    function longestCommonPrefix($strs)
    {
        $isCommonPrefix = function ($length) use ($strs) {
            $str0 = substr($strs[0], 0, $length);
            $count = count($strs);
            for ($i = 1; $i < $count; $i++) {
                $str = $strs[$i];
                for ($j = 0; $j < $length; $j++) {
                    if ($str0[$j] != $str[$j]) {
                        return false;
                    }
                }
            }
            return true;
        };
        if (empty($strs)) {
            return "";
        }

        $minPos = 0;
        foreach ($strs as $k => $str) {
            if (strlen($str) < strlen($strs[$minPos])) {
                $minPos = $k;
            }
        }

        $low = 0;
        $high = strlen($strs[$minPos]); //最大可共用的字符串长度
        while ($low < $high) {
            $mid = (int)(($high - $low + 1) / 2 + $low);
            if ($isCommonPrefix($mid)) {
                $low = $mid;
            } else {
                $high = $mid - 1;
            }
        }
        return substr($strs[0], 0, $low);
    }
}

每日算法-4 最长公共前缀_第4张图片

你可能感兴趣的:(算法)