剑指offer第二版面试题11:旋转数组的最小数字(JAVA版)

题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。

解题思路:
1、暴力解法,从头到尾遍历一次,我们就能找出最小的元素,复杂度为O(n),但是没有利用输入的旋转数组的特性,肯定达不到面试官的要求。
2、二分查找,这里的数组可以看成两个有序的子数组,二分查找对有序数组非常有效,复杂度为O(logn)。

具体分析:
1、先分析数组的特点,这两个有序的数组,前一个数组的所有值都大于等于后一个数组的值,最小值应该出现在后一个数组的第一个元素上。
2、二分查找缩小查找范围依赖于中间值和待查找值的比较。 设置两个指针,index1指向第一个元素,index2指向最后一个元素。 如果中间indexMid指向的元素大于或者等于index1指向的元素,那么,最小的元素一定在indexMid之后。如果indexMid指向的元素小于或者等于index2指向的元素,那么最小元素一定在indexMid之前或者就是indexMid所指向的元素。 就是利用这种判断条件来不断缩小查找范围。
3、结束条件:
最终index1会指向前一个子数组的最后一个元素,index2会指向后一个子数组的第一个元素,两者之间的距离为1。而index2指向的就是最小的元素。
4、特殊情况:
如果被旋转的个数为0,也就是只有一个升序的数组,这时候没有必要去查找,因为第一个元素就是最小的元素。
还有在查找中经常遇到的一种情况,就是有相同元素的情况。 比如 {1, 0, 1, 1, 1} 是{0, 1, 1, 1, 1}的一个旋转。index1、index2、indexMid指向的元素值都为1,这时候不能判断最小值所在的范围,所以需要只能顺序遍历。

代码如下:

public class Solution {
    public static Integer min(int[] array){
        if (array == null || array.length == 0) {
            return null;
        }

        int low=0;
        int high=array.length-1;
        int mid=low;//如果这本身就是一个递增数组

        //如果进入这个循环说明是旋转数组
        while(array[low]>=array[high]){
            if(high-low==1){
                mid=high;
                break;
            }

            mid=(low+high)/2;
            //如果high,low,mid指向同一个元素,则该数组中右重复的数字,则只能顺序查找
            if (array[mid] >= array[low]) {
                low = mid;
            } else if (array[mid] <= array[high]) {
                high = mid;
            }
        }
        return array[mid];
    }
    //顺序查找
    public static int minInOrder(int[] array) {
        int min = array[0];
        for (int i = 1; i < array.length; i++) {
            if (array[i] < min) {
                min = array[i];
            }
        }
        return min;
    }
    public static void main(String[] args) {
        int[] array = {3,4,5,1,2};
        Integer result = min(array);
        System.out.println(result);
    }
}

原文地址:https://www.cnblogs.com/xhlwjy/p/11259566.html

时间: 2024-08-18 10:06:56

剑指offer第二版面试题11:旋转数组的最小数字(JAVA版)的相关文章

【剑指offer】面试题 11. 旋转数组的最小数字

面试题 11. 旋转数组的最小数字 题目描述 题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非递减排序的数组的一个旋转, 输出旋转数组的最小元素. 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1. NOTE:给出的所有元素都大于0,若数组大小为0,请返回0. 解答 复杂度:O(logN) + O(1) public class Solution { public int minNumberInRotateArray(int

剑指offer第二版面试题7:二叉树的下一个节点(JAVA版本)

题目:给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回.注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针. 分析: 根据中序遍历的特点,要找到一个节点的下一个节点无非就是三种情况: 1.有右子树,这时只需要把其右孩子作为下一个遍历的(并不是要找的)节点,然后沿着该节点的左子树(如果有的话)出发,直到遇到叶子节点,那么该叶子节点就是其下一个要找的节点: 2.没有右子树,则判断该节点是否是其父节点的左孩子,如果是则其下一个要找的节点是其父节点: 3.如果不是其父节点

剑指Offer 11. 旋转数组的最小数字

12345678910111213141516171819202122232425262728293031323334353637383940414243 public class { public int minNumberInRotateArray(int[] array) { int index1 = 0; int index2 = array.length - 1; int indexMid = 0; if (array.length == 0) { return 0; } while

剑指offer面试题8——旋转数组的最小数字

题目1386:旋转数组的最小数字 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:6708 解决:1505 题目描述: 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素.例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1. 输入: 输入可能包含多个测试样例,对于每个测试案例, 输入的第一行为一个整数n(1<= n<=1000000):代表旋转数组的元素个数. 输入的第二行包括n

【剑指Offer学习】【面试题8 : 旋转数组的最小数字】

题目: 把一个数组最开始的若干个元素搬到数组的末尾, 我们称之数组的旋转.输入一个递增排序的数组的一个旋转, 输出旋转数组的最小元素.例如数组{3,4, 5, 1, 2 }为{ l1,2,3, 4,5}的一个旋转,该数组的最小值为1 实现代码如下: public class Test08 { /** * 把一个数组最开始的若干个元素搬到数组的末尾, 我们称之数组的旋转. * 输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素. * 例如数组{3, 4, 5, 1, 2}为{l ,2, 3,

面试题08_旋转数组的最小数字——剑指offer系列

题目描述: 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素. 例如:数组{3, 4, 5, 1 , 2} 是 数组{1,2,3,4,5}的一个旋转,该数组最小的数是1. 我们要做的就是找到这个旋转后数组的最小数. 解题思路: 思路1:直接遍历数组,找到最小的数,简单粗暴,时间复杂度O(n),空间复杂度O(1). 一般情况下,能够做到思路一的时空复杂度就很好了,但是这个题目,还可以有更好的思路,将时间复杂度降低. 思路2:

剑指offer-面试题8.旋转数组的最小数字

题目:把一个数组最开始的若干个元素搬到数据的末尾,我们称之为 数组的旋转.输入一个递增排序的数组的一个旋转,输出旋转数组 的最小元素.例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该 数组的最小值为1. 这道题可以使用类似于二分查找的思想,算法思路如下: 1.假设有一个旋转数组A,我们设两个索引p1,p2 2.p1指向为数组第一个元素,p2指向为数组最后一个元素 3.取p3为数组中的中间元素 4.比较p3指向的元素与p1,p2.若p3>p1,则说明前半个    子数组为递增数

面试题:旋转数组的最小数字

题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个递增的排序的数组的一个旋转,输出旋转数组的最小元素.例如输入{1,2,3,4,5}的一个旋转为{3,4,5,1,2},该数组的最小值为1. 分析:首先想到的肯定是遍历一遍找出最小的元素,但是这样的时间复杂度为o(n),且没有利用到旋转数组的特性.观察可得,旋转数组可以分为两个有序的子数组.而且前一个数组的元素均大于后一个数组.这个发现对于我们解题将起到一个至关重要的作用.而更神奇的是最小的元素刚好是这两个子数组的分界

【剑指offer】面试题51:数组中的逆序对

题目 * 面试题51:数组中的逆序对 * 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对. * 输入一个数组,求出这个数组中的逆序对的总数P. * 并将P对1000000007取模的结果输出. 即输出P%1000000007 思路 1.暴力 ,时间复杂度O(n^2) 2.归并排序的思路 :时间复杂度O(nlogn) * (1) 先将数组分成两半,递归分别计算左半边的逆序对数目leftCnt 和右半边的逆序对数目rightCnt * (2)再计算合并之后新增的逆序对