zoukankan      html  css  js  c++  java
  • [LeetCode] 34. Search for a Range 搜索一个范围(Find First and Last Position of Element in Sorted Array)

    原题目:Search for a Range, 现在题目改为: 34. Find First and Last Position of Element in Sorted Array

    Given an array of integers nums sorted in ascending order, 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].

    Example 1:

    Input: nums = [5,7,7,8,8,10], target = 8
    Output: [3,4]
    Example 2:

    Input: nums = [5,7,7,8,8,10], target = 6
    Output: [-1,-1]

    给一个有序整数数组中,寻找相同目标值的起始和结束位置,限定了时间复杂度为O(logn)。

    解法:二分法,典型的二分查找法的时间复杂度,先对原数组使用二分查找法,找出其中一个目标值的位置,然后向两边搜索找出起始和结束的位置。

    Java:

    public class Solution {
    	public int[] searchRange(int[] A, int target) {
    		int start = Solution.firstGreaterEqual(A, target);
    		if (start == A.length || A[start] != target) {
    			return new int[]{-1, -1};
    		}
    		return new int[]{start, Solution.firstGreaterEqual(A, target + 1) - 1};
    	}
    
    	//find the first number that is greater than or equal to target.
    	//could return A.length if target is greater than A[A.length-1].
    	//actually this is the same as lower_bound in C++ STL.
    	private static int firstGreaterEqual(int[] A, int target) {
    		int low = 0, high = A.length;
    		while (low < high) {
    			int mid = low + ((high - low) >> 1);
    			//low <= mid < high
    			if (A[mid] < target) {
    				low = mid + 1;
    			} else {
    				//should not be mid-1 when A[mid]==target.
    				//could be mid even if A[mid]>target because mid<high.
    				high = mid;
    			}
    		}
    		return low;
    	}
    }  

    Python:

    class Solution(object):
        def searchRange(self, nums, target):
            """
            :type nums: List[int]
            :type target: int
            :rtype: List[int]
            """
            # Find the first idx where nums[idx] >= target
            left = self.binarySearch(lambda x, y: x >= y, nums, target)
            if left >= len(nums) or nums[left] != target:
                return [-1, -1]
            # Find the first idx where nums[idx] > target
            right = self.binarySearch(lambda x, y: x > y, nums, target)
            return [left, right - 1]
    
        def binarySearch(self, compare, nums, target):
            left, right = 0, len(nums)
            while left < right:
                mid = left + (right - left) / 2
                if compare(nums[mid], target):
                    right = mid
                else:
                    left = mid + 1
            return left
    
        def binarySearch2(self, compare, nums, target):
            left, right = 0, len(nums) - 1
            while left <= right:
                mid = left + (right - left) / 2
                if compare(nums[mid], target):
                    right = mid - 1
                else:
                    left = mid + 1
            return left
    
        def binarySearch3(self, compare, nums, target):
            left, right = -1, len(nums)
            while left + 1 < right:
                mid = left + (right - left) / 2
                if compare(nums[mid], target):
                    right = mid
                else:
                    left = mid
            return left if left != -1 and compare(nums[left], target) else right
    

    C++:

    class Solution {
    public:
        vector<int> searchRange(vector<int>& nums, int target) {
            const auto start = lower_bound(nums.cbegin(), nums.cend(), target);
            const auto end = upper_bound(nums.cbegin(), nums.cend(), target);
            if (start != nums.cend() && *start == target) {
                return {start - nums.cbegin(), end - nums.cbegin() - 1};
            }
            return {-1, -1};
        }
    };
    
    class Solution2 {
    public:
        vector<int> searchRange(vector<int> &nums, int target) {
            const int begin = lower_bound(nums, target);
            const int end = upper_bound(nums, target);
    
            if (begin < nums.size() && nums[begin] == target) {
                return {begin, end - 1};
            }
    
            return {-1, -1};
        }
    
    private:
        int lower_bound(vector<int> &nums, int target) {
            int left = 0;
            int right = nums.size();
            // Find min left s.t. A[left] >= target.
            while (left < right) {
                const auto mid = left + (right - left) / 2;
                if (nums[mid] >= target) {
                    right = mid;
                } else {
                    left = mid + 1;
                }
            }
            return left;
        }
    
        int upper_bound(vector<int> &nums, int target) {
            int left = 0;
            int right = nums.size();
            // Find min left s.t. A[left] > target.
            while (left < right) {
                const auto mid = left + (right - left) / 2;
                if (nums[mid] > target) {
                    right = mid;
                } else {
                    left = mid + 1;
                }
            }
            return left;
        }
    };
    

      

      

    All LeetCode Questions List 题目汇总

  • 相关阅读:
    Android学习笔记14:Tween Animation动画的实现
    Android学习笔记17:单项选择RadioButton和多项选择CheckBox的使用
    北国的雪
    Android学习笔记11:图像的平移、旋转及缩放
    三极管基本放大电路解析
    51单片机中data,idata,xdata,pdata的区别
    充电开关制作
    慢慢学Linux驱动开发,第五篇,初探设备模型概念
    慢慢学Linxu驱动开发,第二篇:启程,模块机制,Hello World
    H桥电机驱动原理与应用
  • 原文地址:https://www.cnblogs.com/lightwindy/p/9667030.html
Copyright © 2011-2022 走看看