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


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

本文采用JavaScript语言解题:一、暴力法  二、递归二分法

一、暴力法

这次所使用的暴力法还蛮欣赏的,紧抓数组的结构性质进行暴力解决

 1 /**
 2  * @param {number[]} numbers
 3  * @return {number}
 4  * 根据数组元素的构造规则,
 5  * 只要遇到比第一个元素小的数,这个数就是数组最小数字,否则第一个元素就是最小数字
 6  */
 7 var minArray = function(numbers) {
 8     if(numbers == null) return numbers;
 9     let length = numbers.length;
10     let pre = numbers[0];
11     for(let i = 1; i < length; i++) {
12         if(numbers[i] < pre) return numbers[i];
13     }
14     return pre;
15 };

 二、递归二分法

“暴力是解决不了问题的”(我们都是斯文人,hh~)

重要的思想收获:

使用二分法去查找数据,其中的数据不一定非得有序;我们只需有能力(数据的存放方式让你有这个能力)知道要查找的东西在这边还是在那边。

 1 /**
 2  * @param {number[]} numbers
 3  * @return {number}
 4  * 二分搜索
 5  * 判断最小值在左半部分还是在右半部
 6  */
 7 var minArray = function (numbers, left = 0, right = numbers.length - 1) {
 8   if (left == right) return numbers[left];
 9   let mid = Math.trunc(left + (right - left) / 2);
10   // 解决存在重复数的情况,消去重复数(消去重复数并不会影响结果,因为被消去的重复数最终还是会剩下一个)
11   while (mid < right && numbers[mid] == numbers[right]) right--;
12   while (mid > left && numbers[mid] == numbers[left]) left++;
13   if (numbers[mid] > numbers[right]) return minArray(numbers, mid + 1, right);
14   //左半部分非升序时,mid可能为最小值(参数right = mid而不是right = mid - 1)
15   else return minArray(numbers, left, mid); 
16 };