1.合并排序数组
对撞指针
非常经典的解法
//合并排序数组
function arrayAdd($arra,$arrb){
$counta = count($arra) - 1;
$countb = count($arrb) - 1;
$arr = [];
$a = $b = 0;
//两个数组都没循环完
while($a<=$counta && $b<=$countb){
if($arra[$a] <= $arrb[$b]){
$arr[] = $arra[$a];
$a++;
}else{
$arr[] = $arrb[$b];
$b++;
}
}
//当数组b循环完但a还有剩余
while($a<=$counta){
$arr[] = $arra[$a];
$a++;
}
//或者数组a循环完但b还有剩余
while($b<=$countb){
$arr[] = $arrb[$b];
$b++;
}
return $arr;
}
$arra = [4,5];
$arrb=[1,2,3,6,7,8];
$a = arrayAdd($arra,$arrb);
var_dump($a);
2.剑指orrer21题:调整数组顺序使奇数位于偶数前面
https://leetcode-cn.com/problems/diao-zheng-shu-zu-shun-xu-shi-qi-shu-wei-yu-ou-shu-qian-mian-lcof/
额外空间法
把奇数放到数组a,偶数放到数组b,再合并,思路简单,虽然费了一点点内存...
class Solution {
/**
* @param Integer[] $nums
* @return Integer[]
*/
function exchange($nums) {
$count = count($nums);
$i=0;
$a = $b = [];
while($i<$count){
if($nums[$i]%2==1){
$a[]=$nums[$i];
}else{
$b[]=$nums[$i];
}
$i++;
}
return array_merge($a,$b);
}
}
其实时间复杂度O(n)很好了,但是开辟了新的数组内存空间,空间也是O(n)级别的
对撞指针
左指针向右寻找双数,右指针向左寻找单数,找到时交换两个数,直到两个指针相遇时结束。
function exchange($nums){
$left = 0;
$right = count($nums)-1;
while($right>$left){
if($nums[$left] %2 == 1){
$left++;
}
elseif($nums[$right] %2 == 0){
$right--;
}
elseif($nums[$left] %2 == 0 && $nums[$right] %2 == 1){
$temp = $nums[$left];
$nums[$left] = $nums[$right];
$nums[$right] = $temp;
}
}
return $nums;
}
内存优化了一点点,时间复杂度没变o(n),但是空间复杂度o(1),因为只用了常量级的几个变量,不随数组增大而改变。
快慢指针
本人最不擅长的解法,很多时候都想不到...
快指针用来遍历数组,去寻找单数以把它往前换,慢指针用来标记当前可以换的位置。
function exchange($nums){
$slow = 0;
for($fast=0;$fast<count($nums);$fast++){
if($nums[$fast] %2 == 1){
$temp = $nums[$fast];
$nums[$fast] = $nums[$slow];
$nums[$slow] = $temp;
$slow++;
}
}
return $nums;
}
时间复杂度o(n),空间复杂度o(1),理解的话会发现这是三种里最简洁的方法。
再次强调,官方执行结果只做参考,且多次执行结果并不相同,算法好坏还需要结合时间、空间复杂度和实际业务中数据来评判。