当你的才华还撑不起你的野心时,你应该静下心去学习 。
题目描述
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。本题是练习二分法的一道经典例题,也是一道常见面试题。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
示例
输入:[3,4,5,1,2]
返回值:1
解题思路
- 初始化: 声明 i, j 双指针分别指向 numsnums 数组左右两端;
- 循环二分: 设 m = (i + j) / 2 为每次二分的中点( “/” 代表向下取整除法,因此恒有 i≤m nums[j] 时: m 一定在 左排序数组 中,即旋转点 x 一定在 [m + 1, j] 闭区间内,因此执行 i = m + 1;
- 当 nums[m] < nums[j] 时: m 一定在 右排序数组 中,即旋转点 x 一定在[i, m] 闭区间内,因此执行 j = m;
- 当 nums[m] = nums[j] 时: 无法判断 m 在哪个排序数组中,即无法判断旋转点 x 在 [i,m] 还是 [m+1,j] 区间中。解决方案: 执行 j = j - 1j=j−1 缩小判断范围,
- 返回值: 当 i = ji=j 时跳出二分循环,并返回 旋转点的值 nums[i] 即可。
寻找旋转数组的最小元素即为寻找 右排序数组 的首个元素 nums[x] ,称 x 为 旋转点 。
时间复杂度 O(logN) : 在特例情况下(例如[1,1,1,1]),会退化到 O(N)。 空间复杂度 O(1) : i , j , m 变量使用常数大小的额外空间。
参考代码 Java版本class Solution {
public:
int minArray(vector& numbers) {
int i = 0, j = numbers.size() - 1;
while (i numbers[j]) i = m + 1;
else if (numbers[m]
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?