本文正在参与掘金团队号上线活动,点击 查看大厂春招职位
一、题目描述:
二、思路分析:
暴力解法
直接遍历一遍数组查找最小值即可。
- 时间复杂度:O(N),这里 N 是数组的长度。
- 空间复杂度:O(1),使用到的临时变量的个数是常数。
二分
参考题解
有了昨天的文章今天再来看这个问题应该简单一些了吧。
官解的这张图很明了,我们可以发现如果我们把区间中间数跟区间右端点的值比较,会得到两种情况,当区间中间的值大于区间右端点的值的时候,说明当前中间值位于最小值左边的区间,此时我们可以直接舍弃中间位置左边的区间。当区间中间的值小于右端点的值的时候,说明当前中间值位于大于最小值右边的区间,所以我们可以直接舍弃区间中间位置右边的元素。从而达到缩减查找区间的目的。
具体到编码的时候,因为一定会存在一个最小值,所以当while循环结束的时候(left == right),返回 nums[left]即可。
- 时间复杂度:O(logN),这里 N 是数组的长度。
- 空间复杂度:O(1),使用到的临时变量的个数是常数。
三、AC 代码:
function findMin($nums) {
$len_n = count($nums);
$left = 0;
$right = $len_n - 1;
if ($nums[$left] < $nums[$right]) {
return $nums[$left];
}
while ($left < $right) {
$mid = (int)(($right - $left) / 2) + $left;
if ($nums[$mid] > $nums[$right]) {
$left = $mid + 1;
} else {
$right = $mid;
}
}
return $nums[$left];
}
四、总结:
这道题有了昨天的非严格升序/降序也能使用二分的思路后,还是能够比较快的分析出做法。