zoukankan      html  css  js  c++  java
  • 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;
        }
    }
    

      

  • 相关阅读:
    Windows性能计数器应用
    Azure Oracle Linux VNC 配置
    Azure 配置管理系列 Oracle Linux (PART6)
    Azure 配置管理系列 Oracle Linux (PART5)
    Azure 配置管理系列 Oracle Linux (PART4)
    Azure 配置管理系列 Oracle Linux (PART3)
    Azure 配置管理系列 Oracle Linux (PART2)
    vagrant多节点配置
    docker基本操作
    LINUX开启允许对外访问的网络端口命令
  • 原文地址:https://www.cnblogs.com/yrbbest/p/4436310.html
Copyright © 2011-2022 走看看