力扣https://leetcode.cn/problems/search-insert-position/
该题目要求 log(n) 的解法,很显然用二分法很合适
<?php
class Solution {
/**
* @param Integer[] $nums
* @param Integer $target
* @return Integer
*/
function searchInsert($nums, $target) {
$low = 0;
$high = count($nums) - 1;
while($low <= $high) {
$mid = $low + (($high - $low) >> 1);
if($nums[$mid] > $target) {
// [$left, $mid) 之间
$high = $mid - 1;
} elseif($nums[$mid] < $target) {
// ($mid, $high) 之间
$low = $mid + 1;
} else {
return $mid;
}
}
return $low;
}
}
$s = new Solution();
$ret = $s->searchInsert([1,3,5,6], 5);
var_dump($ret);
assert($ret == 2);
$ret = $s->searchInsert([1,3,5,6], 2);
assert($ret == 1);
// $ret = $s->searchInsert([1,3,5,6], 7);
// assert($ret == 4);
力扣https://leetcode.cn/problems/first-bad-version/
这个题的左右指针边界需要特殊注意
<?php
class VersionControl {
public $totalVersionNumber = 1;
public function setTotalVersionNumber(int $n) {
$this->totalVersionNumber = $n;
}
public function getTotalVersionNumber():int {
return $this->totalVersionNumber;
}
public function isBadVersion($n) {
if($this->getTotalVersionNumber() == 5) {
if($n > 3) return true;
return false;
}
if($this->getTotalVersionNumber() == 1) {
return false;
}
}
}
class Solution extends VersionControl {
/**
* @param int $n
* @return int
*/
function firstBadVersion1($n) {
$this->setTotalVersionNumber(5);
if($n == 1) return 1;
$low = 0;
$high = $n;
while($low <= $high) {
$mid = $low + (($high - $low) >> 1);
$midIsBad = $this->isBadVersion($mid);
$beforeIsOk = $mid == 1 || !$this->isBadVersion($mid - 1);
if($midIsBad && $beforeIsOk) {
return $mid;
}
if($midIsBad) {
$high = $mid -1;
} else {
$low = $mid + 1;
}
}
return 1;
}
function firstBadVersion($n) {
$this->setTotalVersionNumber(5);
if($n == 1) return 1;
$low = 1;
$high = $n;
while($low < $high) {
$mid = $low + (($high - $low) >> 1);
if($this->isBadVersion($mid)) {
$high = $mid;
} else {
// 版本正确, 向前退一个版本
$low = $mid + 1;
}
}
return $low;
}
}
$s = new Solution();
$ret = $s->firstBadVersion(4);
var_dump($ret);
assert($ret == 4);
$ret = $s->firstBadVersion(1);
assert($ret == 1);