forked from wangzheng0822/algo
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
350c323
commit c078ee3
Showing
1 changed file
with
191 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,191 @@ | ||
<?php | ||
|
||
/** | ||
* 找到第一个=value的元素 | ||
* @param array $numbers | ||
* | ||
* @return void | ||
* @date 2018/11/27 | ||
* @author yuanliandu <[email protected]> | ||
*/ | ||
function findFirstEqual(array $numbers,$find) { | ||
$length = count($numbers); | ||
$low = 0; | ||
$high = $length - 1; | ||
while($low <= $high) { | ||
$mid = $low + (($high-$low)>>1); | ||
if($numbers[$mid] > $find) { | ||
$high = $mid - 1; | ||
}else if($numbers[$mid] < $find) { | ||
$low = $mid + 1; | ||
}else { | ||
/** | ||
* 如果是第一个元素,或之前一个元素不等于我们要找的值 | ||
* 我们就找到了第一个=find的element | ||
*/ | ||
if($mid==0 || $numbers[$mid-1]!=$find) { | ||
return $mid; | ||
}else { | ||
$high = $mid - 1; | ||
} | ||
} | ||
} | ||
|
||
return -1; | ||
} | ||
|
||
/** | ||
* 找到最后一个=find的元素 | ||
* @param array $numbers | ||
* @param [type] $find | ||
* | ||
* @return void | ||
* @date 2018/11/27 | ||
* @author yuanliandu <[email protected]> | ||
*/ | ||
function findLastEqual(array $numbers,$find) { | ||
$length = count($numbers); | ||
$low = 0; | ||
$high = $length - 1; | ||
while($low <= $high) { | ||
$mid = $low + (($high-$low)>>1); | ||
if($numbers[$mid] > $find) { | ||
$high = $mid - 1; | ||
}else if($numbers[$mid] < $find) { | ||
$low = $mid + 1; | ||
}else { | ||
/** | ||
* 如果mid是最后一个元素的index | ||
* 或mid后一个元素!=我们要找的值 | ||
* 则找到了最后一个=find的value | ||
*/ | ||
if($mid==$length-1 || $numbers[$mid+1]!=$find) { | ||
return $mid; | ||
}else { | ||
$low = $mid + 1; | ||
} | ||
} | ||
} | ||
|
||
return -1; | ||
} | ||
|
||
/** | ||
* 找到第一个大于等于find的元素 | ||
* @param array $numbers | ||
* @param [type] $find | ||
* | ||
* @return void | ||
* @date 2018/11/27 | ||
* @author yuanliandu <[email protected]> | ||
*/ | ||
function findFirstGreaterEqual(array $numbers,$find) { | ||
$length = count($numbers); | ||
$low = 0; | ||
$high = $length - 1; | ||
while($low <= $high) { | ||
$mid = $low + (($high-$low)>>1); | ||
if($numbers[$mid] >= $find) { | ||
if ($mid == 0 || $numbers[$mid-1] < $find) { | ||
return $mid; | ||
}else { | ||
$high = $mid - 1; | ||
} | ||
}else { | ||
$low = $mid + 1; | ||
} | ||
} | ||
return -1; | ||
} | ||
|
||
/** | ||
* 找到最后一个小于等于find的元素 | ||
* @param array $numbers | ||
* @param [type] $find | ||
* | ||
* @return void | ||
* @date 2018/11/27 | ||
* @author yuanliandu <[email protected]> | ||
*/ | ||
function findLastLessEqual(array $numbers,$find) { | ||
$length = count($numbers); | ||
$low = 0; | ||
$high = $length - 1; | ||
while($low <= $high) { | ||
$mid = $low + (($high-$low)>>1); | ||
if($numbers[$mid] <= $find) { | ||
if($mid==$length-1 || $numbers[$mid+1]> $find) { | ||
return $mid; | ||
} | ||
$low = $mid + 1; | ||
}else { | ||
$high = $mid - 1; | ||
} | ||
} | ||
return -1; | ||
} | ||
|
||
|
||
|
||
|
||
|
||
/** | ||
* 循环数组中找指定元素 | ||
* @param array $numbers | ||
* @param [type] $find | ||
* | ||
* @return void | ||
* @date 2018/11/27 | ||
* @author yuanliandu <[email protected]> | ||
*/ | ||
function searchCircularArray(array $numbers,$find) { | ||
$length = count($numbers); | ||
$low = 0; | ||
$high = $length - 1; | ||
|
||
while($low <= $high) { | ||
$mid = $low + (($high-$low)>>1); | ||
if($numbers[$mid] === $find) { | ||
return $mid; | ||
} | ||
|
||
if($numbers[$low] > $numbers[$mid]) { | ||
// 后半部分是有序数组 | ||
if(($numbers[$mid] < $find) && ($numbers[$high] >= $find)) { | ||
if($numbers[$high] === $find) return $high; | ||
//在后半个区间内 | ||
$low = $mid + 1; | ||
}else { | ||
$high = $mid - 1; | ||
} | ||
}else { | ||
// 前半部分是有序的 | ||
if(($numbers[$low] <= $find) && ($numbers[$mid] > $find)) { | ||
// 在有序区间内 | ||
if($numbers[$low] === $find) return $low; | ||
$high = $mid - 1; | ||
}else { | ||
$low = $mid + 1; | ||
} | ||
} | ||
|
||
} | ||
return -1; | ||
} | ||
|
||
/*** | ||
* 测试 | ||
*/ | ||
$numbers = [1,2,3,3,3,4,5,6,8,11,13]; | ||
$find = 3; | ||
|
||
var_dump(findFirstEqual($numbers,$find));//找到第一个等于find的元素 | ||
var_dump(findFirstGreaterEqual($numbers,$find));//找到第一个大于等于find的元素 | ||
var_dump(findLastEqual($numbers,$find));//找到最后一个=find的元素 | ||
var_dump(findLastLessEqual($numbers,$find));//找到最后一个小于等于find的元素 | ||
|
||
|
||
//测试在循环数组中找到指定数字 | ||
$numbers = [9,10,1,2,3,4,5,6,7,8]; | ||
$find = 2; | ||
var_dump(searchCircularArray($numbers,$find)); |