34. 在排序数组中查找元素的第一个和最后一个位置

https://leetcode.cn/problems/find-first-and-last-position-of-element-in-sorted-array/

class Solution {
    public int[] searchRange(int[] nums, int target) {
        int start,end;
        int mid;
        start=0;
        end=nums.length;
        if(nums.length==0){
            return new int[]{-1,-1};
        }
        
        while(start<=end){
            mid=(end-start)/2;
            if(nums[mid]<target){
                start=mid+1;
            }else if(nums[mid]>target){
                end=mid-1;
            }else if(nums[mid]==target){
                if(mid-1>=0&&nums[mid-1]==target){
                   return new int[]{mid-1,mid};
                }else if(mid+1<nums.length&&nums[mid+1]==target){
                    
                    return new int[]{mid,mid+1};
            
                }else{
                    return new int[]{mid,mid};
                }
            }
        }
        return new int[]{-1,-1};

        
    }
}

上述代码超时
以下为改进版本

// 解法2
// 1、首先,在 nums 数组中二分查找 target;
// 2、如果二分查找失败,则 binarySearch 返回 -1,表明 nums 中没有 target。此时,searchRange 直接返回 {-1, -1};
// 3、如果二分查找成功,则 binarySearch 返回 nums 中值为 target 的一个下标。然后,通过左右滑动指针,来找到符合题意的区间

class Solution {
	public int[] searchRange(int[] nums, int target) {
		int index = binarySearch(nums, target); // 二分查找
		
		if (index == -1) { // nums 中不存在 target,直接返回 {-1, -1}
			return new int[] {-1, -1}; // 匿名数组 
		}
		// nums 中存在 targe,则左右滑动指针,来找到符合题意的区间
		int left = index;
		int right = index;
        // 向左滑动,找左边界
		while (left - 1 >= 0 && nums[left - 1] == nums[index]) { // 防止数组越界。逻辑短路,两个条件顺序不能换
			left--;
		}
        // 向左滑动,找右边界
		while (right + 1 < nums.length && nums[right + 1] == nums[index]) { // 防止数组越界。
			right++;
		}
		return new int[] {left, right};
    }
	
	/**
	 * 二分查找
	 * @param nums
	 * @param target
	 */
	public int binarySearch(int[] nums, int target) {
		int left = 0;
		int right = nums.length - 1; // 不变量:左闭右闭区间
		
		while (left <= right) { // 不变量:左闭右闭区间
			int mid = left + (right - left) / 2;
			if (nums[mid] == target) {
				return mid;
			} else if (nums[mid] < target) {
				left = mid + 1;
			} else {
				right = mid - 1; // 不变量:左闭右闭区间
			}
		}
		return -1; // 不存在
	}
}
class Solution {
    public int[] searchRange(int[] nums, int target) {
        // 记录开始的下标
        int start = -1;
        // 记录结束的下标
        int end = -1;

        // 遍历数组nums
        for(int i = 0; i < nums.length; i++){
            if(nums[i] == target){
                if(start == -1){
                    // 当前值与目标值相等,记录开始的下标
                    start = i;
                }
                // 更新end
                end = i;
            }
        }
        // 返回答案
        int[] ans = {start,end};
        return ans;
    }
}


AC

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值