旋转数组的最小数字
2016-09-27 16:24
155 查看
题目: 把一个数组最
旋转数组的特点:
(1)递增排序的数组旋转之后的数组可划分为两个排序的子数组;
(2)前面的子数组的元素都大于或等于后面子数组的元素;
(3)最小的元素刚好是两个子数组的分界线;
(4)旋转数组在一定程度上是有序的;
在有序的数组中可以用二分查找实现O(logn)的查找,我们也可用二分查找的思想寻找旋转数组的最小数字。
思路:
1. 设置两个指针,初始状态第一个指针指向前面子数组的第一个元素,第二个指针指向后面子数组的最后一个元素;
2. 找到两个指针的中间元素;
3.若其大于等于第一个指针指向的元素,则说明其在前面的子数组中,且显然最小元素在中间元素的右边,若其小于等于第二个指针指向的元素,则说明其在后面的子数组中,且显然最小元素在中间元素的左边。
如此,便可以缩小搜索范围,减少时间复杂度,最终第一个指针指向前面子数组的最后一个元素,而第二个指针指向后面子数组的第一个元素,它们处于相邻位置,而第二个指针指向的刚好是最小的元素。
注意:当两个指针指向的数字及它们中间的数字三者相等时,无法判断中间数字位于前面的子数组还是后面的子数组,也就无法移动两个指针来缩小查找的范围,此时只能用顺序查找的方法。
例如:数组{1,0,1,1,1}和数组{1,1,1,0,1}都可看成是递增数组{0,1,1,1,1}的旋转。第一种情况,中间数字位于后面的子数组,第二种情况,中间数字位于前面的子数组。
(5)按旋转规则,第一个元素应该是大于或等于最后一个元素的;
但也有特例:若把排序数组的前0个元素搬到最后面,及排序数组本身,仍是数组的一个旋转,此时数组中的第一个数字是最小的数字。
Result:
参考:
C++版本:
http://blog.csdn.net/htyurencaotang/article/details/9385995
旋转数组的特点:
(1)递增排序的数组旋转之后的数组可划分为两个排序的子数组;
(2)前面的子数组的元素都大于或等于后面子数组的元素;
(3)最小的元素刚好是两个子数组的分界线;
(4)旋转数组在一定程度上是有序的;
在有序的数组中可以用二分查找实现O(logn)的查找,我们也可用二分查找的思想寻找旋转数组的最小数字。
思路:
1. 设置两个指针,初始状态第一个指针指向前面子数组的第一个元素,第二个指针指向后面子数组的最后一个元素;
2. 找到两个指针的中间元素;
3.若其大于等于第一个指针指向的元素,则说明其在前面的子数组中,且显然最小元素在中间元素的右边,若其小于等于第二个指针指向的元素,则说明其在后面的子数组中,且显然最小元素在中间元素的左边。
如此,便可以缩小搜索范围,减少时间复杂度,最终第一个指针指向前面子数组的最后一个元素,而第二个指针指向后面子数组的第一个元素,它们处于相邻位置,而第二个指针指向的刚好是最小的元素。
注意:当两个指针指向的数字及它们中间的数字三者相等时,无法判断中间数字位于前面的子数组还是后面的子数组,也就无法移动两个指针来缩小查找的范围,此时只能用顺序查找的方法。
例如:数组{1,0,1,1,1}和数组{1,1,1,0,1}都可看成是递增数组{0,1,1,1,1}的旋转。第一种情况,中间数字位于后面的子数组,第二种情况,中间数字位于前面的子数组。
(5)按旋转规则,第一个元素应该是大于或等于最后一个元素的;
但也有特例:若把排序数组的前0个元素搬到最后面,及排序数组本身,仍是数组的一个旋转,此时数组中的第一个数字是最小的数字。
public class ReverseMinNumber08 { public int search(int[] nums){ int len =nums.length; if(nums==null|| len<=0) return Integer.MAX_VALUE; int st=0; //首部 int etd = len-1; //末尾 //如果数组为空则返回 //使用二分法查找 //最终第一个指针指向前面子数组的最后一个元素,而第二个指针会指向后面子数组的第一个元素,也就是它们最终会指向两个相邻的元素,而第二个指针指向的刚好是最小的元素 while(etd-st!=1){ int mid = (st +etd)/2; //若中间元素大于首部元素(说明是在前面的递增子数组中),则说明,最小的元素应该在后半部分,此时将指向首部的st指向中间位置 if(nums[mid]>nums[st]){ st=mid; }else if(nums[mid]<nums[etd]){ //若中间元素小于首部元素(说明是在后面的递增子数组中),则说明,最小的元素应该在前半部分,此时将指向尾部的etd指向中间位置 etd=mid; } //当st,etd,mid所指位置元素都相等时,无法判断,则需要使用顺序查找的方法 else if(nums[st]==nums[mid] && nums[etd]==nums[mid]) { return setpSearch(nums); } } return nums[etd]; } //顺序查找 public int setpSearch(int[] nums){ int len = nums.length; int result = nums[0]; for(int i=0;i<len;i++){ if(nums[i]<result){ result = nums[i]; break; } } return result; } public static void main(String[] args) { int [] nums = new int []{5,6,2,4}; int [] nums2 = new int[]{1,0,1,1,1}; int [] nums3 =new int[]{1,1,1,0,1}; int [] nums4 = new int[]{0,0,1,1,1}; ReverseMinNumber08 r = new ReverseMinNumber08(); System.out.println(r.search(nums)); System.out.println(r.search(nums2)); System.out.println(r.search(nums3)); System.out.println(r.search(nums4)); } }
Result:
2 0 0 0
参考:
C++版本:
http://blog.csdn.net/htyurencaotang/article/details/9385995
相关文章推荐
- 旋转数组的最小数字
- 面试题8:旋转数组的最小数字 ***
- 1386:旋转数组的最小数字 @jobdu
- 旋转数组的最小数字
- 剑指 offer set 3 旋转数组的最小数字
- 旋转数组的最小数字
- 【九度OJ1386】|【剑指offer8】旋转数组的最小数字
- 面试题8:旋转数组的最小数字
- [剑指Offer]10.旋转数组的最小数字
- 九度oj 第3题 旋转数组的最小数字 何海涛:《剑指Offer:名企面试官精讲典型编程题》
- 旋转数组的最小数字
- [剑指offer][面试题08]求旋转数组的最小数字
- 面试题8:旋转数组中的最小数字
- 第9天 旋转数组的最小数字
- 题目1386:旋转数组的最小数字
- 旋转数组的最小数字
- 《剑指offer》面试题8—旋转数组的最小数字
- 每日一题(27) - 旋转数组的最小数字
- 旋转数组的最小数字
- 旋转数组的最小数字