https://leetcode.com/problems/longest-common-prefix/submissions/
Approach 1: Horizontal scanning
* Solution.php
<?php
class Solution {
/**
* @param $haystack string
* @param $needle string
* @return int
*/
private static function indexOf($haystack, $needle) {
$j = 0;
$m = strlen($haystack);
$n = strlen($needle);
for ($i = 0; $i < $m && $j < $n; $i++) {
if ($needle[$j] === $haystack[$i]) {
$j += 1;
} else {
$j = 0;
}
}
if ($i >= $m && $j < $n) {
return -1;
}
return $i - $j;
}
/**
* @param $s string
* @param $start int
* @param $end int
* @return bool|string
*/
private static function substring($s, $start, $end) {
// $t = "";
// for ($i = $start; $i < $end; $i++) {
// $t .= $s[$i];
// }
// return $t;
return substr($s, $start, $end - $start);
}
/**
* @param String[] $strs
* @return String
*/
public function longestCommonPrefix($strs) {
if (!isset($strs[0])) {
return "";
}
// 假设公共前缀就是数组第0个元素
$prefix = $strs[0];
$le = count($strs);
// 遍历第1个到最后1个
for ($i = 1; $i < $le; $i++) {
// 测试公共前缀
while (self::indexOf($strs[$i], $prefix) !== 0) {
// 前缀超长 缩短1位再试
$prefix = self::substring($prefix, 0, strlen($prefix)-1);
if (empty($prefix)) {
return "";
}
}
}
return $prefix;
}
}
Test cases:
* index.php
<?php
include "Solution.php";
$sln = new Solution();
$a = ["flower","flow","flight"];
printf("%s\n", $sln->longestCommonPrefix($a));
$a = ["leets","leetcode","leet", "leeds"];
printf("%s\n", $sln->longestCommonPrefix($a));
$a = ["aa","a"];
printf("%s\n", $sln->longestCommonPrefix($a));
$a = ["dog","racecar","car"];
printf("%s\n", $sln->longestCommonPrefix($a));
fl
lee
a
Approach 2: Vertical scanning
* Solution.php
<?php
class Solution {
/**
* @param $s string
* @param $start int
* @param $end int
* @return bool|string
*/
private static function substring($s, $start, $end) {
return substr($s, $start, $end - $start);
}
/**
* @param String[] $strs
* @return String
*/
public function longestCommonPrefix($strs) {
$n = count($strs);
if (is_null($strs) || $n === 0) {
return "";
}
$le = strlen($strs[0]);
for ($i = 0; $i < $le; $i++) {
$c = $strs[0][$i];
for ($j = 1; $j < $n; $j++) {
if ($i === strlen($strs[$j]) || $strs[$j][$i] !== $c) {
return self::substring($strs[0], 0, $i);
}
}
}
return $strs[0];
}
}
Approach 3: Divide and conquer
* Solution.php
<?php
class Solution {
/**
* @param $s string
* @param $start int
* @param $end int
* @return bool|string
*/
private static function substring($s, $start, $end) {
return substr($s, $start, $end - $start);
}
/**
* @param $left string
* @param $right string
* @return string
*/
private static function commonPrefix($left, $right) {
$m = strlen($left);
$n = strlen($right);
$min = $m < $n ? $m : $n;
for ($i = 0; $i < $min; $i++) {
if ($left[$i] != $right[$i]) {
return self::substring($left,0, $i);
}
}
return self::substring($left, 0, $min);
}
/**
* @param $strs String[]
* @param $l int
* @param $r int
* @return string
*/
private static function lcp($strs, $l, $r) {
if ($l >= $r) {
return $strs[$l];
}
$mid = floor($l + $r) / 2;
$lcpLeft = self::lcp($strs, $l, $mid);
$lcpRight = self::lcp($strs, $mid+1, $r);
return self::commonPrefix($lcpLeft, $lcpRight);
}
/**
* @param String[] $strs
* @return String
*/
public function longestCommonPrefix($strs) {
$n = count($strs);
if (is_null($strs) || $n===0) {
return "";
}
return self::lcp($strs, 0, $n-1);
}
}
Approach 4: Binary search
class Solution {
/**
* @param $s string
* @param $start int
* @param $end int
* @return bool|string
*/
private static function substring($s, $start, $end) {
return substr($s, $start, $end - $start);
}
/**
* @param $s string
* @param $t string
* @return bool
*/
private static function startsWith($s, $t) {
for ($i = 0; isset($t[$i]); $i++) {
if ($s[$i] !== $t[$i]) {
return false;
}
}
return true;
}
/**
* @param $strs String[]
* @param $len int
* @return bool
*/
private static function isCommonPrefix($strs, $len) {
$str1 = self::substring($strs[0], 0, $len);
$n = count($strs);
for ($i = 1; $i < $n; $i++) {
if (!self::startsWith($strs[$i], $str1)) {
return false;
}
}
return true;
}
/**
* @param String[] $strs
* @return String
*/
public function longestCommonPrefix($strs) {
$n = count($strs);
if (is_null($strs) || $n===0) {
return "";
}
$minLen = 2147483647;
foreach ($strs as $str) {
$minLen = min($minLen, strlen($str));
}
$low = 0;
$high = $minLen;
while ($low <= $high) {
$middle = floor(($low + $high) / 2);
if (self::isCommonPrefix($strs, $middle)) {
$low = $middle + 1;
} else {
$high = $middle - 1;
}
}
return self::substring($strs[0], 0, floor(($low + $high)/2));
}
}