无序的一组数字中找到最长连续子序列长度
例:
1 20 4 21 22 最长连续数列是20 21 22,输出就是3
12 15 31 5 14 23 13 最长数列是12 13 14 15,输出就是4
思路:
首先有一种方法是大家都能想到的,先把这组数字从小到大排序,然后找出最长的连续数列,计算长度,但是笔试的时候要求最优时间复杂度,所以先排序只是一种方法,不是最优方法。所以带来了下面的方法,拿出一个元素来在数组当中寻找该元素+1,+2,+3…找到之后,将找到的元素从数组中删除,这个时候就需要该初始元素必须为此连续数列最小值,so我们先在数组中寻找该元素-1的元素,若存在,就跳出这次循环,对下个元素进行操作,若没有就证明此元素是连续数列的最小值,可进行++操作。
方法:
public function selNum($arr){
$num = count($arr);//由于下面有删除数组操作,提前把数组初始长度赋值给$num,避免循环当中出错
for ($i = 0;$i< $num;$i++){
if (in_array($arr[$i]-1,$arr)){
continue;//挨个取数组元素找有没有比它小1的元素,有就continue跳出当前循环
} else {
$tmp = $arr[$i];
$beg = $arr[$i];//把这个元素赋值给一个变量,便于计算数列长度
while(in_array($tmp,$arr)){//循环依次找比该元素+1,+2,+3...直到找不到为止,就是该数列最大长度
$key = array_search($tmp,$arr);
unset($arr[$key]);
$tmp++;
}
if ($tmp != $arr[$i]){
$max[] = intval($tmp-$beg);//计算数列长度添加到数组中
}
}
}
return $max;
}
使用:
$str = "13 14 21 15 23 18 56 43 12 22 4 16 17 11";
$res = explode(' ',$str);
$info = $this->selNum($res);
var_dump($info);die;
输出:
array(5) { [0]=> int(3) [1]=> int(1) [2]=> int(1) [3]=> int(1) [4]=> int(8) }
//然后一目了然,最大的就是8位