• 34. Search for a Range


    题目:

    Given a sorted array of integers, find the starting and ending position of a given target value.

    Your algorithm's runtime complexity must be in the order of O(log n).

    If the target is not found in the array, return [-1, -1].

    For example,
    Given [5, 7, 7, 8, 8, 10] and target value 8,
    return [3, 4].

    链接:  http://leetcode.com/problems/search-for-a-range/  

    题解:

    考察Binary Search的结束条件。 使用两次Bianry Search,一次搜索左边界,一次搜索右边界,最后需要比较一下左边界是否 <= 右边界,假如条件不成立则target不在数组中。

    Time Complexity - O(n), Space Complexity - O(1)

    public class Solution {
        public int[] searchRange(int[] nums, int target) {
            int[] res = {-1, -1};
            if(nums == null || nums.length == 0)
                return res;
            int lolo = 0, lohi = nums.length - 1, hilo = 0, hihi = nums.length - 1;
            
            while(lolo <= lohi) {                   //try find left end
                int mid = lolo + (lohi - lolo) / 2;
                if(nums[mid] < target)
                    lolo = mid + 1;
                else
                    lohi = mid - 1;
            }
            
            while(hilo <= hihi) {                   //try find right end
                int mid = hilo + (hihi - hilo) / 2;
                if(nums[mid] > target)
                    hihi = mid - 1;
                else
                    hilo = mid + 1;
            }
            
            if(lolo <= hihi) {                     //if target exist
                res[0] = lolo;
                res[1] = hihi;
            }
            
            return res;
        }
    }

    二刷:

    Java:

    要使用两次binary search来分别搜索target值的最左端和最右端。最后需要判断一下求出来的left 是否<= right,否则 [1], 1这样的test case会过不了

    public class Solution {
        public int[] searchRange(int[] nums, int target) {
            int[] res = {-1, -1};
            if (nums == null || nums.length == 0) {
                return res;
            }
            int lo = 0, hi = nums.length - 1;
            while (lo <= hi) {
                int mid = lo + (hi - lo) / 2;
                if (target > nums[mid]) {
                    lo = mid + 1;
                } else {
                    hi = mid - 1;
                }
            }
            int left = lo;
            lo = 0;
            hi = nums.length - 1;
            while (lo <= hi) {
                int mid = lo + (hi - lo) / 2;
                if (target >= nums[mid]) {
                    lo = mid + 1;
                } else {
                    hi = mid - 1;
                }
            }
            int right = hi;
            if (left <= right) {
                res[0] = left;
                res[1] = right;
            }
            return res;
        }
    }

    三刷:

    这回写得比较奇怪。原理都一样,都是使用两次binary search,但是改变了一些变量和条件。

    要注意搜索左边界时,遇到mid = target时我们hi = mid - 1,最后返回的边界index是lo。搜索右边界时,遇到mid = target我们lo = mid + 1,最后返回的边界index是hi。也需要判断一下没有搜索到的case,这就是代码里的两个独立if语句的作用。

    Java:

    public class Solution {
        public int[] searchRange(int[] nums, int target) {
            int[] res = {-1, -1};
            if (nums == null) return res;
            int lo = 0, hi = nums.length - 1;
            while (lo <= hi) {
                int mid = lo + (hi - lo) / 2;
                if (nums[mid] < target) lo = mid + 1;
                else hi = mid - 1;
            }
            if (lo > nums.length - 1 || nums[lo] != target) return new int[] {-1, -1};
            
            res[0] = lo;
            lo = 0;
            hi = nums.length - 1;
            while (lo <= hi) {
                int mid = lo + (hi - lo) / 2;
                if (nums[mid] > target) hi = mid - 1;
                else lo = mid + 1;
            }
            if (hi < 0 || nums[hi] != target) return new int[] {-1, -1};
            res[1] = hi;
            return res;
        }
    }

    Update:

    public class Solution {
        public int[] searchRange(int[] nums, int target) {
            int[] res = {-1, -1};
            if (nums == null) return res;
            int lo = 0, hi = nums.length - 1;
            while (lo <= hi) {
                int mid = lo + (hi - lo) / 2;
                if (nums[mid] < target) lo = mid + 1;
                else hi = mid - 1;
            }
            if (lo > nums.length - 1 || nums[lo] != target) return res;
            
            res[0] = lo;
            hi = nums.length - 1;
            while (lo <= hi) {
                int mid = lo + (hi - lo) / 2;
                if (nums[mid] > target) hi = mid - 1;
                else lo = mid + 1;
            }
            res[1] = hi;
            return res;
        }
    }
    

      

  • 相关阅读:
    淘宝技术这十年(淘宝技术大学校长解密淘宝十年)
    Go Web编程(Go语言性能好、语法简单、开发效率高!)
    辨别虚假流量的十二种方法
    收获,不止Oracle(顶级专家盖国强、冯春培、黄志洪等联袂力荐)
    演说之禅:职场必知的幻灯片秘技(第2版)(全彩)
    篮球词汇(转)
    Xilinx 网站资源导读
    乔布斯2005年在斯坦福毕业典礼的演讲稿
    FPGA中BRAM初始化文件格式的总结_ALTERA/XILINX
    写给还在上班的人(转)
  • 原文地址:https://www.cnblogs.com/yrbbest/p/4436310.html
Copyright © 2020-2023  润新知