zoukankan      html  css  js  c++  java
  • 【力扣】34. 在排序数组中查找元素的第一个和最后一个位置

    给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。

    如果数组中不存在目标值 target,返回 [-1, -1]。

    进阶:

    你可以设计并实现时间复杂度为 O(log n) 的算法解决此问题吗?
     

    示例 1:

    输入:nums = [5,7,7,8,8,10], target = 8
    输出:[3,4]
    示例 2:

    输入:nums = [5,7,7,8,8,10], target = 6
    输出:[-1,-1]
    示例 3:

    输入:nums = [], target = 0
    输出:[-1,-1]
     

    提示:

    0 <= nums.length <= 105
    -109 <= nums[i] <= 109
    nums 是一个非递减数组
    -109 <= target <= 109

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    时间复杂度:O(n)  空间复杂度O(1)   --时间复杂度并不能满足题目要求 没有利用到数组升序排列的条件

    public int[] searchRange(int[] nums, int target) {
            if(nums.length == 0){
                return new int[]{-1,-1};
            }
            int startIndex = -1;
            int endIndex = -1;
            for(int i = 0; i < nums.length ; i++){
                if(target == nums[i]){
                    if(startIndex == -1){
                        //得到开始索引
                        startIndex = i;
                    }
                    endIndex = i;
                }
                if(nums[i] > target){
                    break;
                }
            }
            return new int[]{startIndex,endIndex};
        }

    由于整个数组是单调递增的,我们可以利用二分法来加速查找的过程

    正常的二分查找过程:

    int binarySearch(int[] nums, int target) {
            int left = 0;
            int right = nums.length - 1; // 注意
    
            while(left <= right) { // 注意
                int mid = (right + left) / 2;
                if(nums[mid] == target)
                    return mid;
                else if (nums[mid] < target)
                    left = mid + 1; // 注意
                else if (nums[mid] > target)
                    right = mid - 1; // 注意
            }
            return -1;
        }

    套入该题中:

    public int[] searchRange(int[] nums, int target) {
            if(nums.length == 0){
                return new int[]{-1,-1};
            }
            int leftIndex = binarySearch(nums,target,true);
    
            int rightIndex = binarySearch(nums,target,false) - 1; //这是减一的原因:是为了找到同targe相同的值的索引
    
            if(leftIndex <= rightIndex && rightIndex < nums.length && nums[leftIndex] == target && nums[rightIndex] == target){
                return new int[]{leftIndex,rightIndex};
            }
            return new int[]{-1,-1};
        }
    
        
        public int binarySearch(int[] nums, int target,boolean biggerAndEqual) {
            int left = 0;
            int right = nums.length - 1; // 注意
    
            int result = nums.length; //这里注意,一定要是nums.length 要不然在外层-1时会有问题
    
    
            while(left <= right) { // 注意
                int mid = (right + left) / 2;
                //如果当前值大于目标值 ,把节点挪到中间,并记录结果
                //如果当前值大于等于目标值且是求左边的索引,那么就 把节点挪到中间,并记录结果
                if(nums[mid] > target || (biggerAndEqual && nums[mid] >= target)){
                    right = mid -1;
                    result = mid;
                }else {
                    left = mid + 1; // 注意
                }                
            }
            return result;
        }
    }

    时间复杂度:O(logn)

    空间复杂度:O(1)

    一个入行不久的Java开发,越学习越感觉知识太多,自身了解太少,只能不断追寻
  • 相关阅读:
    NYOJ 625 笨蛋的难题(二)
    NYOJ 102 次方求模
    ZJU Least Common Multiple
    ZJUOJ 1073 Round and Round We Go
    NYOJ 709 异形卵
    HDU 1279 验证角谷猜想
    BNUOJ 1015 信息战(一)——加密程序
    HDU 1202 The calculation of GPA
    "蓝桥杯“基础练习:字母图形
    "蓝桥杯“基础练习:数列特征
  • 原文地址:https://www.cnblogs.com/fengtingxin/p/14071640.html
Copyright © 2011-2022 走看看