代码随想录打卡打一天|704.二分查找,27.移除元素

代码随想录打卡打一天|704.二分查找,27.移除元素

二分查找

左闭右开或者左闭右闭都表示mid的取值范围,

mid取值

​ left=0,right=nums.length(左闭右开,左边界取,右边界无效,不取)

​ or

​ left=0, right = nums.length - 1(左闭右闭,左边界取,右边界有效,取)

随着范围不断缩小,

终止条件

​ 不论是左闭右开还是左闭右闭要遍历完整个数组,但由于mid的取值范围不同,导致终止条件不同

​ while(left<right) (左闭右开,终止时:right=left,因为right本来就无效,所以整个数组遍历完毕)

​ or

​ while(left<=right) (左闭右闭,终止时:right<left,该情况下左右边界都有效,必须查看right=left,整个数组遍历完毕)

比较时的判断条件

左闭右开:
if(nums[mid] > target){
	right = mid ;
}else if(nums[mid] < target){
	left = mid + 1;
}else{
	return mid;
}
左闭右闭
if(nums[mid] > target){
	right = mid - 1 ;
}else if(nums[mid] < target){
	left = mid + 1;
}else{
	return mid;
}

区别在于右边界有无效,左闭右开,右边界无效,则同样去无效的mid

左闭右闭,右边界有效,则取有效的mid - 1

整体代码

左闭右开

class Solution {
    public int search(int[] nums, int target) {
        //左闭右开
        int left = 0 , right = nums.length;
        while(left < right){
            int mid = left + (right - left)/2;
            if(nums[mid] > target){
                right = mid ;
            }else if(nums[mid] < target){
                left = mid + 1;
            }else{
                return mid;
            }
        }
        return -1;
    }
}

左闭右闭

class Solution {
    public int search(int[] nums, int target) {
        //左闭右闭
        int left = 0 , right = nums.length - 1;
        while(left <= right){
            int mid = left + (right - left)/2;
            if(nums[mid] > target){
                right = mid - 1;
            }else if(nums[mid] < target){
                left = mid + 1;
            }else{
                return mid;
            }
            
        }
        return -1;
    }

}

拓展题

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

class Solution {
    public int[] searchRange(int[] nums, int target) {
        int start = startIndex(nums,target);
        int end = endIndex(nums,target);
        if(start == -2 || end == -2 )return new int[]{-1,-1};
        if(end - start >= 1)return new int[]{start,end};
        return new int[]{-1,-1};
    }
    //返回第一个下标,或者返回第一个小于的下标,
    //[5,7,7,8,8,10]
    //8
    int startIndex(int[] nums , int target){
        int left = 0 , right = nums.length-1;
        int find= -2;
        while(left <= right){
            int mid = left + (right - left)/2;
            if(nums[mid] > target){
                right = mid-1;
            }else if(nums[mid] < target){
                left = mid + 1;
            }else{
                //如果相等,则判断右边一个是否符合条件
                
                find=right;
                right = mid - 1;
                

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

移除元素

一个简单的快慢指针(一个简单的快慢口儿,在家就能做(狗头.jpg))

class Solution {
    public int removeElement(int[] nums, int val) {
        //慢指针记录最终答案,快指针扫描数组,如果符合条件则用快指针指向的元素,覆盖慢指针指向的元素
        int low = 0;
        for(int fast = 0 ; fast < nums.length ; fast++){
            if(nums[fast] != val){
                nums[low++] = nums[fast];
            }
        }
        return low;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值