• 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;
        }
    }
    

      

  • 相关阅读:
    Python之路第十二天,高级(5)-Python操作Mysql,SqlAlchemy
    Python之路第十二天,高级(4)-Python操作rabbitMQ
    Python之路第十一天,高级(3)-线程池
    day11 消息队列、多线程、多进程、协程
    day10 多进程、多线程(一)
    day09编程之socket
    day08面向对象(二)
    day07面向对象(初级篇)
    day06反射和正则
    day05开发 (字符串格式化和常用模块)
  • 原文地址:https://www.cnblogs.com/yrbbest/p/4436310.html
Copyright © 2020-2023  润新知