时隔3周,我又回来啦!
今天的题目如下所示:
这是一道有趣的题,虽然这里显示的是简单,但那时下来的链接指向的是一道困难的题,所以这道题的难度要怎么算呢?还是折中算他中等吧😄
这道题题干不长,还挺好理解的,就是一个递增的数组前面有一部分被截取接到了剩下那部分的后面去,,组成了一个新数组,然后要找到这个新数组的最小值。这道题一眼看过去,可以直接一个min()或者进行遍历,找到第一个比前一位数字小的数字输出就好了😝不过这道题肯定没有那么简单,因为这样时间复杂度并不低。
按照题目相关标签给的提示,这道题应该用二分法来进行求解。因为这题的数组是一个升序数组旋转得到的,所以二分法的思路也不是很复杂:将数组中部的元素和最右边的元素进行比较,如果中间的元素比最右边的元素大,说明最小值在中间元素的右侧,因此要将右侧列表切片继续二分查找;如果中间的元素比最右边的元素小,说明最小值在中间元素的左侧,因此要将左侧列表切片继续二分查找。如果相同的话,emmm,这是个好问题,我改了很多次之后才决定用递归来解决中间的元素和最右边的元素相同的问题,因为有相同的元素存在,所以并不能直接确定最小的数字是在哪一侧的列表切片中。
比如说数组[2,2,2,0,1],中间元素是2,右侧元素是1,2>1,所以截取右边的列表[0,1]继续二分查找。
恶心一点,比如说这个列表[10,10,10,1,10],中间元素是10,右侧元素也是10,我并不能马上确定最小元素到底是在哪一边,所以只能两边都再查找一下。
代码比较简洁,如下所示:
class Solution:
def minArray(self, numbers: List[int]) -> int:
while True:
lens = len(numbers) - 1
if lens <= 2:
return min(numbers)
i = lens // 2 + 1 if lens%2 == 1 else lens // 2
if numbers[i] > numbers[lens]:
numbers = numbers[i+1:]
elif numbers[i] == numbers[-1]:
return min(self.minArray(numbers[i+1:]), self.minArray(numbers[:i+1]))
else:
numbers = numbers[:i+1]
这样的话,虽然没有双百,但是结果也还是比较好看的: