記錄全部算法相關知識。寫算法時,能夠先寫test case,這樣比較容易把握和思考。
如下算法均可以直接跑。
1.冒泡算法php
<?php $arr = [2,1,4,3,8,9,7,6,5]; print_r(bubbleSort($arr)); function bubbleSort($arr) { $length = count($arr); for($i=0;$i<$length;$i++) { for($j=$i+1;$j<$length;$j++) { if ($arr[$i] > $arr[$j]) { //這種形式比較簡便易讀 list($arr[$i], $arr[$j]) = array($arr[$j], $arr[$i]); } } } return $arr; }
2.快速排序。簡單思路,隨機挑選一個數組中的值,以它爲標準,小於他的放在她的左邊,大於他的放在他的右邊。以後遞歸,最後全部的值都會排列好。算法
<?php $arr = [8,7,6,5,4,0, -1, -3,3,2,1]; print_r(quickSort($arr)); function quickSort($arr) { $length = count($arr); //判斷結束的標準,單一變量 if ($length <= 1) return $arr; //取random整數,隨機防止特殊狀況時間複雜度升爲n^2 $index = rand(0, $length - 1); $reference = $arr[$index]; $left = $right = array(); //注意是小於length便可 for ($i=0;$i<$length;$i++) { if ($i!=$index) { if ($arr[$i] <= $reference) { array_push($left, $arr[$i]); } else { array_push($right, $arr[$i]); } } } $left = quickSort($left); $right = quickSort($right); return array_merge($left, [$reference], $right); }
3.從兩個數組中找出相同的數編程
<?php $arr1 = [5,4,3,2,1]; $arr2 = [4,5,6,7,8]; print_r(uniqueNumber($arr1, $arr2)); function uniqueNumber($arr1, $arr2) { sort($arr1); sort($arr2); $length1 = count($arr1); $length2 = count($arr2); $index1 = $index2 = 0; $container = []; while ($index1 < $length1 && $index2 < $length2) { if($arr1[$index1] < $arr2[$index2]) { $index1++; } else if ($arr1[$index1] > $arr2[$index2]) { $index2++; } else { $container[] = $arr1[$index1]; //放入container以後,不要忘記增長index $index1++; $index2++; } } return array_unique($container); }
4.重寫shuffle函數,打亂一個數組數組
<?php $arr = [2,3,4,5,6,7,8,9]; print_r(shuffleRewrite($arr)); //這邊不能用shuffle,由於是內置函數。 function shuffleRewrite($arr) { $length = count($arr); for($i=0;$i<$length;$i++) { $index = rand(0, $length-1); list($arr[$i], $arr[$index]) = array($arr[$index], $arr[$i]); } return $arr; }
5.分離字母和數字。一個string中有字母數字,分離並用:分割dom
<?php $numAlpha = "abc123dfg4jkl567ddd"; print_r(numAlphaSplit($numAlpha)); function numAlphaSplit($numAlpha) { $number = preg_split('/[a-z]+/', $numAlpha, -1, PREG_SPLIT_NO_EMPTY); $alpha = preg_split('/\d+/', $numAlpha, -1, PREG_SPLIT_NO_EMPTY); $result = ''; for($i=0;$i<count($number);$i++) { $result .= $number[$i] . ':' . $alpha[$i]; } //不要忘了其中一個可能會多,有沒有更好的方法? $result .= isset($alpha[count($number)])?$alpha[count($number)]:''; return $result; }
6.約瑟夫環問題
相關題目:一羣猴子排成一圈,按1,2,…,n依次編號。而後從第1只開始數,數到第m只,把它踢出圈,從它後面再開始數, 再數到第m只,在把它踢出去…,如此不停的進行下去, 直到最後只剩下一隻猴子爲止,那隻猴子就叫作大王。要求編程模擬此過程,輸入m、n, 輸出最後那個大王的編號。函數
<?php $m = 3; $n = 3; echo roundCount($m, $n); function roundCount($m, $n) { $roundTable = range(1, $m); while (count($roundTable) > 1) { for ($i=0;$i<$n-1;$i++) { $pop = array_shift($roundTable); array_push($roundTable, $pop); } array_shift($roundTable); } return $roundTable[0]; }
7.二分法ui
<?php $arr = [1,3,5,7,9,11,13]; echo binarySearch($arr, 11); function binarySearch($arr, $index) { $length = count($arr); $left = 0; $right = $length-1; while ($left <= $right) { //注意要在while裏邊求mid值 $mid = intval(($left+$right)/2); //用arr[$mid]和要找的值比較,用mid來增減位置 if ($arr[$mid] > $index) { $right = $mid - 1; } else if ($arr[$mid] < $index) { $left = $mid + 1; } else { return $mid; } } return -1; }
8.找出一組數中連續的最大和3d
<?php $arr = [-4, -2, 4, -3, 6, -2, 9, -3]; echo maxSum($arr); function maxSum($arr) { $currentSum = 0; $maxSum = 0;//數組元素全爲負的狀況,返回最大數 for ($i = 0; $i < count($arr); $i++) { if ($currentSum >= 0) { if ($maxSum < $currentSum) $maxSum = $currentSum; $currentSum += $arr[$i]; } else { $currentSum = $arr[$i]; } } return $maxSum; }
9.3sum. 排序好的數列,複雜度n^2。若是沒有排列好,能夠先用sortcode
<?php $arr = [-8,-7,-6,-4,-2,0,1,2,3,4,5,6,7]; print_r(sum3($arr)); function sum3($arr) { $result = []; for ($i=0;$i<count($arr)-1;$i++) { //左邊的從index以後開始就能夠,會覆蓋前面的 $left = $i + 1; $right = count($arr) -1; //有這個right>left,因此不用擔憂i,left,right相等 while ($right > $left) { $sum = $arr[$left] + $arr[$i] + $arr[$right]; if ($sum < 0) { $left++; } else if ($sum > 0) { $right--; } else { $set = array($arr[$left], $arr[$i], $arr[$right]); $result[] = $set; //不要忘記++,不然死循環 $left++; $right--; } } } return $result; }