2020.7.22 力扣每日

 

 1 class Solution {
 2     public int minArray(int[] numbers) {
 3         int left = 0, right = numbers.length - 1;
 4         while(left < right){
 5             int mid = (right - left) / 2 + left;
 6             if(numbers[mid] < numbers[right]){    
 7                 right = mid;
 8             }
 9             else if(numbers[mid] > numbers[right]){
10                     left = mid + 1;
11                  }
12             else --right;
13         }
14         return numbers[left];
15     }
16 }

解题思路:

   对于该题,暴力法即顺序查找的思路及其简单,即找到第一个小于前一个值的元素,将其返回即可。但这样的时间复杂度为O(N),并不推荐。所以此处考虑更优的查找方法,二分查找,降低时间复杂度。首先分析题目,对于二分查找来说,nums[left],nums[right],nums[mid]的情况必须全部分析清楚,根据不同的情况,移动left,right指针,来返回即可。

   若题目的所给数组无重复数字,假设最终返回元素的节点为i,由于无重复元素,则必定[left,i-1]的值都大于[i,right]的值,所以比较时,若nums[mid] > nums[right],则移动left,left = mid +1,若nums[mid] < nums[right] 则移动right,right = mid。最终返回nums[left]即可。

注意点:

   但该题中并未标明无重复元素,需考虑第三种情况nums[mid] == nums[right]。对于该情况,我们无法确定mid是处于[left,i]之间还是[i,right]之间,但无论如何,对于i处的元素来说,nums[i]只可能小于或等于nums[right],但无论如何都一定出现在right左侧,所以此处使用--right,使right指针前移。

时间复杂度:O(logN)

空间复杂度:O(1)

题后总结:

   优:使用了二分查找优化了算法

   差:对于情况的考虑不够周到,还需多多练习

posted @ 2020-07-22 23:46  小小码农-安  阅读(200)  评论(0编辑  收藏  举报