标签:while 空间 部分 dup ati n+1 print 重复 cat
题目一:
在一个长度为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)));
标签:while 空间 部分 dup ati n+1 print 重复 cat
原文地址:https://www.cnblogs.com/cyworz/p/11212412.html