zoukankan      html  css  js  c++  java
  • 剑指 Offer 11. 旋转数组的最小数字

    题目链接

    https://leetcode-cn.com/problems/xuan-zhuan-shu-zu-de-zui-xiao-shu-zi-lcof/

    题目描述

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

    输入:[3,4,5,1,2]
    输出:1
    
    输入:[2,2,2,0,1]
    输出:0

    解题思路

    方式一:暴力枚举

    初始化变量ans为INT_MAX,for循环扫描一遍输入的数组并迭代更行ans的值(当数组中元素的值小于ans,则更新ans的值),时间复杂度O(n)

    方式二:双指针

    该数组有个特性,可以看成是由一个有序序列拆分成俩个部分的有序数列,所以比较连续两个元素的大小即可。

    方式三:二分查找

    普通的二分查找算法都是在有序数组中寻找是否出现每个值,在本题中,数组不在完全有序且题目并没有给我们一个需要寻找的值。

    题目提供的数组部分有序,且我们只需要比较numbers[mid]、numbers[l]、numbers[r]这三个元素的大小即可,所以我们依旧可以使用二分查找算法,把时间复杂度从O(n)将为O(logn)

    伪代码如下:

     为什么更新r值的时候不需要+1,而l值需要呢?

    题目要找的是最小值,所以当numbers[mid] < numbers[l]的时候,numbers[mid]很可能是我们所要寻找的答案,而当numbers[mid] > numbers[r],因为numbers[r]的值已经小于numbers[mid],所以numbers[mid]不可能是我们要找的答案,所以需要更新l的值为mid + 1。

    如果出现numbers[mid] == numbers[l] == numbers[r] == value的时候该怎么办?例如numbers = [3,3,1,3]、numbers = [1, 1, 1, 2, 3, 1]

    无论value值是否是我们所需要的最小值,我们都可以把它删除,因为一共有3个value值,删除最右边的一个value元素不会造成影响。

    AC代码

    暴力枚举

    class Solution {
        public int minArray(int[] numbers) {
            // 暴力枚举
            int ans = 123456789;
            for(int i = 0; i < numbers.length; i++)
            {
                if(numbers[i] < ans) ans = numbers[i];
            }
            return ans;
        }
    }

    双指针

    class Solution {
        public int minArray(int[] numbers) {       
            //双指针
            int l = 0;
            int r = numbers.length - 1;
            while(l < r){
                if(numbers[l] > numbers[l+1]) return numbers[l+1];
                if(numbers[r] < numbers[r-1]) return numbers[r];
                l++;
                r--;
            }
            return numbers[0];
        }
    }

    二分查找

    class Solution {
        public int minArray(int[] numbers) {       
            //二分
            int l = 0;
            int r = numbers.length - 1;
            while(l <= r)
            {
                int mid = (l + r) / 2;
                if(numbers[mid] < numbers[l]){
                    r = mid;
                }else if(numbers[mid] > numbers[r]){
                    l = mid + 1;
                }else if(numbers[mid] == numbers[r]){
                    r--;
                }else{ //代表数组已经是一个完全有序的数组
                    break;
                }
            }
            return numbers[l];
        }
    }
  • 相关阅读:
    Django_05_模板
    Django_04_视图
    Django_03_后台管理
    Django_02_创建模型
    Django_01_创建图书管理项目
    Djang简介
    day_03比特币转账的运行原理
    day_02比特币的转账机制及其7个名词
    day01_人类社会货币的演变
    Socket问题
  • 原文地址:https://www.cnblogs.com/XDU-Lakers/p/13361688.html
Copyright © 2011-2022 走看看