码迷,mamicode.com
首页 > 其他好文 > 详细

Leetcode 35. Search in rotated sorted array

时间:2019-02-03 11:08:58      阅读:174      评论:0      收藏:0      [点我收藏+]

标签:art   优化   if判断   题目   注意事项   start   font   判断语句   ret   

今天做了Leetcode第35题,总结一下这个题以及非常重要的一个考点:二分法

二分法:


二分法的核心思想是每次把范围缩小一半,时间复杂度为O(logn)。当brute force求解之后的时间复杂度是O(n),但是面试官还要求优化的时候就要考虑二分法了,因为比O(n)还要好的就是O(logn)了,而O(logn)基本上就是二分法的时间复杂度,这就是根据时间复杂度推算该用什么算法的一种技巧。

我们的设置start以及end之后,while循环的作用是缩小我们要寻找的范围,不一定非得在while循环里面设置很多的判断语句。可以等while循环结束跳出来之后再进行if判断,这样可以使while循环的逻辑和作用更干净,不会导致混乱。

二分法中要注意的几个点:

(一)二分法的境界:1. 模板;2. XXOO;3. half half

XXOO的意思是将数组中的元素分类成XXOO,这样我们可以将二分法转换成求last X或者first O的问题。比如数组为[4,5,6,7,6,5,4,3], 要在这个数组中用二分法找到最大值,可以将4567划分为一组,这一组的判断条件是呈上升趋势,然后将6543化为一组,这个题就变成了find last X(上升区间中的最后一个);把问题转换成find first O(下降区间的第一个)与上一个同理。在此建议一般转化成求find first O的问题。

(二)二分法的一些注意事项:

  1. while循环的判断条件: start + 1 < end

  2. mid的计算: mid = start + (end - start) / 2; //完全是为了装逼,告诉面试官你考虑到了 mid = (start + end) / 2这个情况中 start + end可能会导致int越界的情况

  3. nums[mid] ==, <, > 这三种情况分开讨论,最后看是否可以合并

  4. 前面说了while循环可以只用来缩小范围,最后再用 nums[start]   nums[end] ? target 比较一下我们最后要return的是什么

 

前面总结的都是二分法的一些知识,针对35这个题目,这个数组是rotated的,属于第三种境界,因为没法套模板,也不能换成XXOO的模型。可以画个图来理解。本题中的数组是:[4,5,6,7,0,1,2]。

画图画出四个象限,在本例中,4,5,6,7为第一段,0,1,2为第二段。切一刀作为mid的位置,mid要么在左边一段,要么在右边一段,如何判断呢?将nums[mid]和nums[start]做比较,如果nums[mid] > nums[start],那么就是落在了左边一段上,如果nums[mid] < nums[start],那么就是落在了右边一段上,这是第一步
//第二步:如何判断应该挪动start到mid还是end到mid呢(针对第一步中的两种不同的情况,方法是不一样的)?就将target和nums[start]、nums[mid]进行比较(如果mid这刀切在了左边的话),要么将target和nums[mid]、nums[end]进行比较(如果mid这刀切在了右边的话).

 public int search(int[] nums, int target) {
        if(nums == null || nums.length == 0) return -1;
        int start = 0, end = nums.length - 1;
        while(start + 1 < end) {
            int mid = start + (end - start) / 2;
            if(nums[mid] == target)
                return mid;
            if(nums[mid] >= nums[start]) {
                if(nums[start] <= target && target <= nums[mid]) {
                    end = mid;
                } else {
                    start = mid;
                }
            } else if(nums[mid] < nums[start]) {
                if(nums[mid] <= target && target <= nums[end]) {
                    start = mid;
                } else {
                    end = mid;
                }
            }
        }
        
        if(nums[start] == target) return start;
        if(nums[end] == target) return end;
        return -1;
    }

 

Leetcode 35. Search in rotated sorted array

标签:art   优化   if判断   题目   注意事项   start   font   判断语句   ret   

原文地址:https://www.cnblogs.com/LiMC-Littlewade/p/10349652.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!