剑指offer——面试题8:旋转数组的最小数字
剑指offer——面试题8:旋转数组的最小数字
Solution1:
自己想的复杂度为O(n)O(n)O(n)的算法,若用二分查找则:
1.代码复杂;2.最坏情况下的二分查找的时间复杂度亦为O(n)O(n)O(n)
class Solution {
public:int minNumberInRotateArray(vector<int> rotateArray) {int n=rotateArray.size();if(n<=1) return n==0? 0:rotateArray[0];for(int i=1;i<n;i++){if(rotateArray[i]<rotateArray[i-1])return rotateArray[i];}return rotateArray[0];}
};
Solution2:书中的思路。参考链接:
https://www.nowcoder.com/profile/648947/codeBookDetail?submissionId=2954831
剑指Offer中有这道题目的分析。这是一道二分查找的变形的题目。
旋转之后的数组实际上可以划分成两个有序的子数组:前面子数组的大小都大于后面子数组中的元素
注意到实际上最小的元素就是两个子数组的分界线。本题目给出的数组一定程度上是排序的,因此我们试着用二分查找法寻找这个最小的元素。
思路:
(1)我们用两个指针left,right分别指向数组的第一个元素和最后一个元素。按照题目的旋转的规则,第一个元素应该是大于最后一个元素的(没有重复的元素)。
但是如果不是旋转,第一个元素肯定小于最后一个元素。
(2)找到数组的中间元素。
中间元素大于第一个元素,则中间元素位于前面的递增子数组,此时最小元素位于中间元素的后面。我们可以让第一个指针left指向中间元素。
移动之后,第一个指针仍然位于前面的递增数组中。
中间元素小于第一个元素,则中间元素位于后面的递增子数组,此时最小元素位于中间元素的前面。我们可以让第二个指针right指向中间元素。
移动之后,第二个指针仍然位于后面的递增数组中。
这样可以缩小寻找的范围。
(3)按照以上思路,第一个指针left总是指向前面递增数组的元素,第二个指针right总是指向后面递增的数组元素。
最终第一个指针将指向前面数组的最后一个元素,第二个指针指向后面数组中的第一个元素。
也就是说他们将指向两个相邻的元素,而第二个指针指向的刚好是最小的元素,这就是循环的结束条件。
到目前为止以上思路很耗的解决了没有重复数字的情况,这一道题目添加上了这一要求,有了重复数字。
因此这一道题目比上一道题目多了些特殊情况:
我们看一组例子:{1,0,1,1,1} 和 {1,1, 1,0,1} 都可以看成是递增排序数组{0,1,1,1,1}的旋转。
这种情况下我们无法继续用上一道题目的解法,去解决这道题目。因为在这两个数组中,第一个数字,最后一个数字,中间数字都是1。
第一种情况下,中间数字位于后面的子数组,第二种情况,中间数字位于前面的子数组。
因此当两个指针指向的数字和中间数字相同的时候,我们无法确定中间数字1是属于前面的子数组(绿色表示)还是属于后面的子数组(紫色表示)。
也就无法移动指针来缩小查找的范围。
#include <iostream>
#include <vector>
#include <string>
#include <stack>
#include <algorithm>
using namespace std;class Solution {
public:int minNumberInRotateArray(vector<int> rotateArray) {int size = rotateArray.size();if(size == 0){return 0;}//ifint left = 0,right = size - 1;int mid = 0;// rotateArray[left] >= rotateArray[right] 确保旋转while(rotateArray[left] >= rotateArray[right]){// 分界点if(right - left == 1){mid = right;break;}//ifmid = left + (right - left) / 2;// rotateArray[left] rotateArray[right] rotateArray[mid]三者相等// 无法确定中间元素是属于前面还是后面的递增子数组// 只能顺序查找if(rotateArray[left] == rotateArray[right] && rotateArray[left] == rotateArray[mid]){return MinOrder(rotateArray,left,right);}//if// 中间元素位于前面的递增子数组// 此时最小元素位于中间元素的后面if(rotateArray[mid] >= rotateArray[left]){left = mid;}//if// 中间元素位于后面的递增子数组// 此时最小元素位于中间元素的前面else{right = mid;}//else}//whilereturn rotateArray[mid];}
private:// 顺序寻找最小值int MinOrder(vector<int> &num,int left,int right){int result = num[left];for(int i = left + 1;i < right;++i){if(num[i] < result){result = num[i];}//if}//forreturn result;}
};int main(){Solution s;//vector<int> num = {0,1,2,3,4,5};//vector<int> num = {4,5,6,7,1,2,3};vector<int> num = {2,2,2,2,1,2};int result = s.minNumberInRotateArray(num);// 输出cout<<result<<endl;return 0;
}
剑指offer——面试题8:旋转数组的最小数字相关推荐
- 剑指offer面试题[8]-旋转数组的最小数字
题目描述 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素. 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个 ...
- 剑指Offer - 面试题11. 旋转数组的最小数字(二分查找)
1. 题目 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素.例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] ...
- 剑指offer面试题11. 旋转数组的最小数字(二分查找)
题目描述 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素.例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的 ...
- 剑指offer(12)旋转数组的最小数字
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素. 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组 ...
- 剑指offe面试题8 旋转数组的最小数字 (java实现)
解题思路: 针对旋转数组的特点,即旋转后,数组的前半部分是有序的,后半部分是有序的. 1.先考虑一般情况:可以参考二分查找的思想,在数组中设置两个指针,一个指向数组的起始位置,一个指向数组的结束位置. ...
- j剑指offer面试题[33]-把数组排成最小的数
题目描述 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个.例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323. 思路: 可以 ...
- 剑指Offer - 面试题45. 把数组排成最小的数(字符串排序)
1. 题目 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个. 示例 1: 输入: [10,2] 输出: "102"示例 2: 输入: [ ...
- 剑指Offer:面试题33——把数组排成最小的数(java实现)(未完待续)
问题描述: 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个.例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323. 思路1: ...
- 【剑指offer-Java版】08旋转数组的最小数字
旋转数组最小数字:暴力方法就是遍历-有效的方法是二分,但是存在失效的情况 几个特别的测试用例需要注意下: 数组中含有多个相同的数字 最小数字就是第一个 public class _Q08 {publi ...
- 剑指offer——面试题51:数组中重复的数字
剑指offer--面试题51:数组中重复的数字 Solution1: 20180910更新.利用数组做一次hash映射,时间复杂度为O(n)O(n)O(n),空间复杂度O(n)O(n)O(n). cl ...
最新文章
- SQL 解决从分组数据中总是挑选第一条数据的问题
- python 线程安全链表_教你用 Python 实现 HashMap 数据结构
- 关于JavaScript中name的意义冲突
- Spring IOC 容器源码分析 - 创建单例 bean 的过程
- AI:大力出奇迹?Bigger is better?AI下一代浪潮?—人工智能的大语言模型(LLMs)的简介、发展以及未来趋势
- Websocket实现Java后台主动推送消息到前台
- VTK:小部件之TexturedButtonWidget
- 在XenApp如何发布SAP的客户端(上)
- 手机修图软件测试,照片秒变高清修图软件APP
- android 工具 lve,Android Studio 4.0 新功能中的Live Layout Inspector详解
- 计算机软件登记委托开发合同,软件委托开发合同
- ArcEngine合并要素
- PDF阅读器开关“手型工具阅读文章”功能
- Vue-第三方库扩展
- web页超过2G以上大视频分片秒传方案
- C语言基础入门48篇_30_二维数组的定义与使用(二维数组的定义:type 数组名[行][列]、二维数组的初始化、二维数组的引用)
- 【DuiLib入门基础】九宫格corner属性详细解释
- S4D440Customcode adaption practice
- Kotlin高仿微信-第6篇-主页-我的
- Java微信开发_Exception_03_errcode:48001 errmsg:api unauthorized hint
热门文章
- Eratosthenes筛法求素数
- linux 永久添加路由表,Linux 添加永久静态路由的方法
- z tree 如何把选中的节点保存为标准的json格式_为什么MongoDB使用B-Tree?
- java显示字母数字组合_Java字母加数字组合比较大小
- 新版linux系统主机最低配置,Linux系统初始配置标准化
- Java应用案例分析_Java应用启动参数实例解析
- python中文字体奇怪_利用python检查 AS400的中文字问题
- centos7默认字体_如何更换CentOS(Linux)系统默认字体?
- tinyint数据类型php筛选时怎么判断_PHP从入门到精通(三)PHP语言基础
- easymock参数_EasyMock捕获参数