最近几天整理了一些php经典算法题,偏基础,欢迎指正。
思路
把猴子放到有序数组里,按顺序把符合要求的unset掉或者放到数组最后,递归循环。
function circle($n,$m)
{
$list = [];
for($i = 1; $i <= $n; $i++)
{
$list[$i] = $i;
}
$array = kick($list, $m);
return implode($array);
}
function kick($array,$m)
{
if(count($array) == 1)
{
return $array;
}
foreach($array as $key => $value)
{
if($key%$m == 0)
{
unset($array[$key]);
}
else
{
array_push($array,$array[$key]);
unset($array[$key]);
}
}
$array = kick($array, $m);
return $array;
}
// 7
echo circle(8,3);
思路
设置统计总数,对单个牛遍历每一年,如果小于15岁同时是4的倍数,总数就加一(生了小牛),如果达到20岁就减一(本体死了),超过20岁跳出循环(总量不会因它变化了)。本题的精华在于,每出生一头小牛,对于它的总年数=总年数-出生之前的年数,这样可以算出它的产出和死亡共计多少牛,同时作为静态变量的总数累加算出结果。
function cow($year)
{
static $sum = 1;
for($i = 1; $i <= $year; $i++)
{
if($i > 20)
{
break;
}
if($i <15 && $i%4 == 0)
{
$sum++;
cow($year - $i);
}
if($i == 20)
{
$sum --;
}
}
return $sum;
}
echo cow(100);
两边是1,其他每个数 = 上一行对应两个数之和
function triangle($n)
{
$base = ['1'=>[1],'2'=>[1,1],'3'=>[1,2,1]];
if($n <= 3)
{
return $base;
}
for($i =4; $i <= $n; $i ++)
{
$temp = [1];
for($j = 0; $j < count($base[$i - 1]) - 1; $j ++)
{
$temp[] = $base[$i - 1][$j] + $base[$i - 1][$j+1];
}
$temp[] = 1;
$base[$i] = $temp;
}
return $base;
}
var_dump(triangle(10));
思路
从第一个数开始,每个数和后面的数比较,把小的放前面,这样经过一次遍历后,最大的数会到最后一位,第二次遍历到倒数第二位即可,以此类推。
function maopao($data)
{
$len = count($data);
for($i = $len; $i > 1; $i --)
{
for($j = 0; $j < $i - 1; $j ++)
{
if($data[$j] > $data[$j + 1])
{
$temp = $data[$j + 1];
$data[$j + 1] = $data[$j];
$data[$j] = $temp;
}
}
}
return $data;
}
var_dump(maopao([5,1,8,3,6,4,9,2,7]));
思路
取出第一位,遍历数组,小于它就放到 left 数组,大于等于它就放到 right 数组,再分别对 left 和 right 数组进行递归排序,形成树状结构,这样当只剩一位时,上方的节点都已排序好,组合即得。
这种算法最优时间复杂度是O(log2n),比冒泡的O(n)要快,最慢的情况一样。
function quick($data)
{
if(count($data) <= 1)
{
return $data;
}
$key = $data[0];
$left = [];
$right = [];
for($i = 1; $i < count($data); $i ++)
{
if($data[$i] < $key)
{
$left[] = $data[$i];
}
else
{
$right[] = $data[$i];
}
}
$left = quick($left);
$right = quick($right);
return array_merge($left,array($key),$right);
}
var_dump(quick([5,1,8,3,6,4,9,2,7]));
思路
每次取中间数对比,大了就和左边数对比,小了就和右边对比,我是截取数组,其实使用左右两个下标,对比后替换下标更节省内存,你们可以试试。
function twoSearch($x, $data)
{
$i = round(count($data)/2);
$middle = $data[$i];
if($x == $middle)
{
return $i;
}
else if($x > $middle)
{
twoSearch($x, array_slice($data, 0, $i));
}
else
{
twoSearch($x, array_slice($data, $i, -1));
}
return false;
}
var_dump(twoSearch(16,[11,12,13,14,15,16,17,18,19,20]));
思路
把字符串分割成数组,去重,再排序。
function character($data)
{
$array = str_split($data);
$array = array_unique($array);
sort($array);
return implode('', $array);
}
var_dump(character('optimization'));
思路
使用php读取文件和文件夹的函数,遍历读取。
function readFile($dir)
{
$data = [];
if($handle = opendir($dir))
{
while($file = readdir($handle) != false)
{
if($file != '.' && $file != '..')
{
if(is_dir($dir.'/'.$file))
{
$data[$file] = readFile($dir.'/'.$file);
}
else
{
$data[] = $file;
}
}
}
closedir($handle);
}
return $data;
}
思路
当一个人走到第n级时,只有两种可能,在n-1级台阶跨一级,或者在n-1级台阶跨两级。
function fibonacci($n)
{
if($n <= 2)
{
return $n == 1 ? 1 : 2;
}
$n = fibonacci($n - 1) + fibonacci($n - 2);
return $n;
}
var_dump(fibonacci(10));