PHP近期常见算法面试题( 二 )


<?phpclass Discount{public $money;public $time;function __construct($money, $time){$this->money = $money;$this->time = $time;}}$discounts = [];for ($i = 0; $i < 10; $i++) {$discount = new Discount(rand(1, 10), time() - rand(1111, 9999));array_push($discounts, $discount);}echo '<pre>';function quick_sort($ds){if (count($ds) <= 1) {return $ds;} else {$left = [];$right = [];$dsCount = count($ds);for ($i = 1; $i < $dsCount; $i++) {if ($ds[$i]->money > $ds[0]->money) {array_push($left, $ds[$i]);} else if ($ds[$i]->money < $ds[0]->money) {array_push($right, $ds[$i]);} else {if ($ds[$i]->time <= $ds[0]->time) {array_push($right, $ds[$i]);} else {array_push($left, $ds[$i]);}}}$left = quick_sort($left);$right = quick_sort($right);return array_merge($left, [$ds[0]], $right);}}$result = quick_sort($discounts);print_r($result);6.有一个文件,里面每一行都是一个url,写一个算法,读取出现最多的五条,及其出现的次数
<?phpfunction make_file(){$urls = ['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p'];$num = count($urls);$file = fopen('data.txt', "w");for ($i = 0; $i < 1000; $i++) {fwrite($file, $urls[rand(0, $num - 1)] . "n");}fclose($file);}//make_file();function get_result($filename, $num){$arr = [];$file = fopen($filename, 'r');while (!feof($file)) {$key = fgets($file);if ($key != "") {array_push($arr, $key);}}fclose($file);$counts = array_count_values($arr);$results = [];$keys = array_keys($counts);print_r($keys);for ($i = 0; $i < $num; $i++) {$key = $keys[0];foreach ($keys as $k) {if ($counts["$k"] > $counts["$key"]) {$key = $k;}}$results["$key"] = $counts["$key"];unset($counts["$key"]);}print_r($results);}get_result('data.txt', 5);7.php实现斐波那契数列
斐波那契数列: 1 1 2 3 5 8 13 21 34 55 …
概念: 前两个值都为1,该数列从第三位开始,每一位都是当前位前两位的和 规律公式为: Fn = F(n-1) + F(n+1) F:指当前这个数列 n:指数列的下标
非递归写法:
<?phpfunction fbnq($n){//传入数列中数字的个数if ($n <= 0) {return 0;}$array[1] = $array[2] = 1; //设第一个值和第二个值为1for ($i = 3; $i <= $n; $i++) { //从第三个值开始$array[$i] = $array[$i - 1] + $array[$i - 2];//后面的值都是当前值的前一个值加上前两个值的和}return $array;}递归写法:
function fbnq($n){if($n <= 0) return 0;if($n == 1 || $n == 2) return 1;return fbnq($n - 1) + fbnq($n - 2);}8.php找到字符数组里最左匹配长度的字符(最长公共前缀匹配算法)
输入: ["flower","flow","flight"]
输出: "fl"
示例 2:
输入: ["dog","racecar","car"]
输出: ""
解释: 输入不存在公共前缀 。
<?php$a = ["flower", "flow", "flww", "flight"];function rep_test($arr){$return_str = '';if (empty($arr))return $return_str;$tmp_arr = [];//声明一个临时的数组foreach ($arr as $v) {$tmp_arr[strlen($v)] = $v;}$min_str = $tmp_arr[min(array_keys($tmp_arr))]; //找到最短长度的字符串$min_len = strlen($min_str); //获取最小长度for ($i = 0; $i < $min_len; $i++) {foreach ($arr as $v) {if ($v[$i] != $min_str[$i]) {break 2;}}}if ($i > 0) {$return_str = substr($min_str, 0, $i);}return $return_str;}echo rep_test($a);?>9.PHP获取字符串中出现次数最多的字符
解法一:(最快速的解法)
<?php$arr = str_split($str);$arr = array_count_values($arr);arsort($arr);print_r($arr);解法二:
<?php$arr = str_split($str);$unique = array_unique($arr);foreach ($unique as $a) {$arr2[$a] = substr_count($str, $a);}arsort($arr2);print_r($arr2);10.PHP算法之无重复字符的最长子串
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度 。
示例 1:
输入: "abcabcbb"输出: 3解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3 。示例 2:
输入: "bbbbb"输出: 1解释: 因为无重复字符的最长子串是 "b",所以其长度为 1 。示例 3:
输入: "pwwkew"输出: 3解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3 。请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串 。
<?phpclass Solution{/*** @param String $s* @return Integer*/function lengthOfLongestSubstring($s){$l = strlen($s); //获取字符串总长度$len = 0;//记录长度$find = ''; //保存截取字符串for ($i = 0; $i < $l; $i++) {$res = strpos($find, $s[$i]); // 查找$find中是否存在if ($res !== false) {$find .= $s[$i];$find = substr($find, $res + 1);} else {$find .= $s[$i];}$len = strlen($find) > $len ? strlen($find) : $len;}return $len;}}


推荐阅读