【Java实现】剑指offer53.1——在排序数组中查找数字(LeetCode34:在排序数组中查找元素的起始位置)

剑指offer53.1——在排序数组中查找数字(LeetCode34:在排序数组中查找元素的起始位置):思路分享

【Java实现】剑指offer53.1——在排序数组中查找数字(LeetCode34:在排序数组中查找元素的起始位置)_第1张图片

《剑指offer》题目和LeetCode主站本质是一样的,想要找到target数目,也需要找到左右边界

题目解析:

在一个排序数组中,找到target的左右边界,从而得到target的数量

第一感觉:二分查找,因为数组是有序的

灵感闪现!!! 灵感闪现!!! 灵感闪现!!!

给定一个数字target,找到它在排序数组中插入的位置!!!

这道题就是二分插入!你品,你细品!

下面说一下具体思路和步骤:

  • 二分查找的基本形式,边界、判断条件构建
  • 首先找右边界:将二分判断的条件修改为nums[mid]<=target,最后返回i作为右边界
  • 同理找到左边界:二分条件设成nums[mid],返回j作为左边界

优化前代码如下:
*代码实现的是《剑指offer》版本,LeetCode只需将边界装进数组返回即可

class Solution {
     
    public int search(int[] nums, int target) {
     
    	//二分边界构建
        int i=0,j=nums.length-1;
        int mid;
        //循环条件
        while(i<=j) {
     
            mid=(i+j)>>1;
            //舍弃所有小于等于target的值,保证i是第一个右边界
            if(nums[mid]<=target) i=mid+1;
            else j=mid-1;
        }
        int right=i;
        //判断是否真的存在target
        if(j>=0 && nums[j]!=target ) return 0;

        i=0;
        while(i<=j) {
     
            mid=(i+j)>>1;
            //舍弃所有大于等于target的值,保证j是左边界
            if(nums[mid]<target) i=mid+1;
            else j=mid-1;
        }
        int left=j;
        return right-left-1;
    }
}

优化后的思想:

  • 第一步找到target在数组中插入的位置
  • 第二步找到(target-1)在数组中插入的位置
  • 两个位置直接相减,就可以得到结果

注意:这里无论寻找的值(target)是否存在,都能够找到合适的索引将其插入数组!也就是开篇的那个想法

优化后的代码如下:

class Solution {
     
    public int search(int[] nums, int target) {
     
        int i=0, j=nums.length-1;
        return (helper(nums,target,i,j)-helper(nums,target-1,i,j));
    }
    private int helper(int[] nums,int target,int i,int j) {
     
        while(i<=j) {
     
            int mid=(i+j)>>1;
            if(nums[mid] <= target) i=mid+1;
            else j=mid-1;
        }
        return i;
    }
}

复杂度分析:

  • 时间复杂度为O(logn),因为是用到二分思想
  • 空间复杂度为O(1),并没有使用额外空间

你可能感兴趣的:(刷题分享,算法,数据结构,java,leetcode,面试)