旋转数组中的最小数字

191 阅读2分钟

小知识,大挑战!本文正在参与「程序员必备小知识」创作活动。

问题

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

力扣链接

leetcode-cn.com/problems/xu…

考察要点

考察对于二分查找算法的深入理解, 不要只局限于单一用途

考察我们思考问题的严谨与全面性, 要做到一丝不苟

首先要认识什么是旋转数组?

旋转数组在数组的分布上又可以分为两个有序的子数组

前面数组中的元素大于等于后面数组中的元素

思路

  1. 定义指向最左边元素的索引left, 指向最右边元素的索引right和指向中间的索引mid

  2. 判断中间索引指向的元素

    它如果大于right索引指向的元素, 则表明mid索引它属于第一个数组的, 则现在将left指向mid+1的位置

    它如果小于right索引指向的元素, 则表明mid索引它属于第二个数组的, 则现在将right指向mid的位置

    它如果等于right索引指向的元素, 则无法判断mid索引指向的元素属于哪个子数组, 则现在将right索引减1

  3. 当left>=right时, 则right索引指向的元素就是要找的最小元素

代码

 public int minArray(int[] list) {
     int length = list.length;
 ​
     // 定义三个索引
     int left = 0;
     int right = length - 1;
     int mid = (right - left) / 2;
 ​
     // 当left索引大于等于right时, 则不再查找
     while (left < right) {
         mid = (right + left) / 2;
         
         // 中间索引属于第二个子数组
         if (list[mid] < list[right]) {
             right = mid;
         } else if (list[mid] > list[right]) { // 中间索引属于第一个子数组
             left = mid + 1;
         } else { // 无法判断中间索引属于哪个子数组
             right--;
         }
     }
     return list[right];
 }

总结

本题考察我们对于二分查找算法的熟练度. 之前我对二分查找的认识还仅局限于整体有序的一组数据中, 现在让我知道了二分查找有更多的用途.

在解决问题时, 我们不要单单只考虑普通的情况, 不要考虑特殊情况, 边界的判断, 测试用例的完善.