2020-12-01

力扣打卡题(二分法)

力扣34题
在这里插入图片描述
解题思路:
1、使用二分法模板直接套用
二分法标准模板

public static int BinSearch(int[] nums, int target){
	if(nums.length< 0)
	return -1;
	int right = nums.length;
	int left = 0;
	while(left <= right){
		int mid = (right - left)/2 + left;//防止越界
		if(nums[mid] <  target)
			left = mid+1;
		else if(nums[mid] > target)
			rigth = mid-1;
		else return mid
	}
	return -1;
}

二分法变体1:查找第一个等于目标值的下标


public int bsearch(int[] a, int n, int value) {
  int low = 0;
  int high = n - 1;
  while (low <= high) {
    int mid =  low + ((high - low) >> 1);
    if (a[mid] > value) {
      high = mid - 1;
    } else if (a[mid] < value) {
      low = mid + 1;
    } else {
      if ((mid == 0) || (a[mid - 1] != value)) return mid;
      else high = mid - 1;
      //如果不满足条件,就说明数组前面还有满足(a[mid-1] == value)的下标
    }
  }
  return -1;
}

二分法变体2:查找最后一个等于目标值的下标


public int bsearch(int[] a, int n, int value) {
  int low = 0;
  int high = n - 1;
  while (low <= high) {
    int mid =  low + ((high - low) >> 1);
    if (a[mid] > value) {
      high = mid - 1;
    } else if (a[mid] < value) {
      low = mid + 1;
    } else {
      if ((mid == n - 1) || (a[mid + 1] != value)) return mid;
      else low = mid + 1;
    }
  }
  return -1;
}

二分法变体3:查找第一个大于等于给定值的元素


public int bsearch(int[] a, int n, int value) {
  int low = 0;
  int high = n - 1;
  while (low <= high) {
    int mid =  low + ((high - low) >> 1);
    if (a[mid] >= value) {
      if ((mid == 0) || (a[mid - 1] < value)) return mid;
      else high = mid - 1;
    } else {
      low = mid + 1;
    }
  }
  return -1;
}

二分法变体4:查找最后一个大于等于给定的元素


public int bsearch7(int[] a, int n, int value) {
  int low = 0;
  int high = n - 1;
  while (low <= high) {
    int mid =  low + ((high - low) >> 1);
    if (a[mid] > value) {
      high = mid - 1;
    } else {
      if ((mid == n - 1) || (a[mid + 1] > value)) return mid;
      else low = mid + 1;
    }
  }
  return -1;
}

最后回到本题使用上述1,2两种变体就可以了

  public int[] searchRange(int[] nums, int target) {
        if(nums.length == 0) return new int[]{-1,-1};
        
        return new int[]{searchLeft(nums,target),searchRight(nums,target)};
    }
    //左边第一个
    public int searchLeft(int[] nums,int target){
        int right = nums.length-1;
        int left = 0;
        while(left <= right){
            int mid = (right-left)/2 + left;
            if(nums[mid] < target){
                left = mid+1;
            }else if(nums[mid] > target){
                    right = mid-1;
                }
            else {
                if(mid == 0 || nums[mid-1] != target){
                     return mid;
                }
                 else right = mid-1;
            }
        }
        return -1;
    }
    //右边第一个
    public int searchRight(int[] nums,int target){
        int right = nums.length-1;
        int left = 0;
        while(left <= right){
            int mid = (right-left)/2 + left;
            if(nums[mid] < target){
                left = mid+1;
            }else if(nums[mid] > target){
                    right = mid-1;
                }
            else {
                if(mid == right || nums[mid+1] != target){
                     return mid;
                }
                 else left = mid+1;
            }
        }
        return -1;
    }

最后附上截图
在这里插入图片描述
第二种方法也是二分法的变体
先找其左边界,再找其右边界即可,注意找左边界的时候,由右侧逼近;找右边界的时候,由左侧逼近

public int[] searchRange(int[] nums, int target) {
        if (nums == null || nums.length == 0) {
            return new int[]{-1, -1};
        }
        return binSearch(nums, 0, nums.length - 1, target);
    }


    private int[] binSearch(int[] nums, int low, int high, int target) {
        if (low >= high) {
            return nums[low] == target ? new int[]{low,low} : new int[]{-1, -1};
        } else {
            int mid = low + (high - low)/2;
            if (nums[mid] == target) {
                // 左右分开查找
                int[] left = binSearch(nums, low, mid-1, target);
                int[] right = binSearch(nums, mid+1, high, target);
                int l = left[0] == -1 ? mid : Math.min(left[0], mid);
                int r = right[1] == -1 ? mid : Math.max(right[1], mid);
                return new int[]{l, r};
            } else if (nums[mid] < target){
                return binSearch(nums, mid+1, high, target);
            } else {
                return binSearch(nums, low, mid-1, target);
            }
        }
    }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值