题目一:
在一个长度为n的数组里的所有数字都在0~n-1的范围内。找出数组中任意一个重读数字。
/** * 找出数组中的重复数字 * 长度为n的数组 所有数字在0~n-1的范围内 * * * @param $num 数组 * @param $length 数组长度 * @return bool */ function getNum($num,$length){ $mark = array(); if (count($num)==0||$length<=0){ return false; } for ($i=0;$i<$length;++$i){ if ($num[$i]<0||$num[$i]>$length-1){ return false; } } for ($i=0;$i<$length;++$i){ while ($num[$i]!=$i){ if ($num[$i]==$num[$num[$i]]){ $mark[] = $num[$i]; break; } $temp = $num[$i]; $num[$i]=$num[$temp]; $num[$temp]=$temp; } } return $mark; } $a = [3,2,4,6,5,2,3,6]; print_r(getNum($a,count($a)));题目二:不修改数组找出重复数字在一个长度为n+1的数组里所有数字都在1~n的范围内,所以必有重复数字。找出任意一个重复数字,但不能修改数组。
/** * 不改变数组 找出任意一个重复数字 * 二分法 * 时间换空间 * @param $number 数组 * @param $length 数组长度 */ function getDuplication($number,$length){ if (count($number)==0||$length<=0){ return false; } $start = 1; $end = $length-1; while($end>=$start){ $middle = (($end-$start)>>1)+$start; //位运算 求中值 $count =countRange($number,$length,$start,$middle) ; if ($end==$start){ if ($count>1){ return $start; }else{ break; } } if ($count>($middle-$start+1)){ $end = $middle; }else{ $start = $middle+1; } } // return -1; } function countRange($num,$length,$start,$end){ if (count($num)==0){ return 0; } $count = 0; for ($i = 0;$i<$length;$i++){ if ($num[$i]>=$start&&$num[$i]<=$end){ ++$count; } } return $count; } $a = [3,2,4,6,5,2,3,6]; print_r(getDuplication($a,count($a)));
原文地址:https://www.cnblogs.com/cyworz/p/11212412.html
时间: 2024-10-09 03:47:30