leetcode33 34 35 81——二分法查找

这篇博客主要讨论了三种与排序数组相关的问题:搜索旋转排序数组、查找元素的第一个和最后一个位置以及搜索插入位置。针对每种问题,提供了详细的解决方案,包括二分查找法的应用和特殊情况的处理。通过这些算法,可以有效地在不同情况的排序数组中找到目标元素或确定插入位置。

33、搜索旋转排序数组

class Solution {
    public int search(int[] nums, int target) {
        if(nums==null) return -1;
        if(nums[0]==target) return 0;
        if(nums[nums.length-1]==target) return nums.length-1;
        
        int l=0;
        int r=nums.length-1;

        while(l<=r){
            int mid=(l+r)/2;

            if(nums[mid]==target) return mid;
            if(nums[l]==target) return l;
            if(nums[r]==target) return r;

            
            if(nums[0] < nums[mid]){
                if(nums[0]<=target&& target<nums[mid]){
                    //0到mid 有序 且target在范围中
                    r=mid-1;
                }else{
                    //有序 但 target不在范围中
                    l=mid+1;
                }
            }else{
                //0 到mid  无序 那么 另外一半 mid到r肯定有序
                if(nums[mid]<target&& target<=nums[r]){
                    l=mid+1;
                }else{
                    r=mid-1;
                }
            }

        }

        return -1;
    }
}

分组之后 一定以某以结点 分为有序和无序

那么通过二分法查找之后,肯定是一半有序 一半无序,无序那一半还可以通过继续二分法进行查找

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

class Solution {
    public int[] searchRange(int[] nums, int target) {
        int[] out=new int[2];
        out[0]=-1;
        out[1]=-1;
        if(nums==null) return out;
        /*if(nums.length==1){
            if(nums[0]==target){
                out[0]=0;
                out[1]=0;
                return out;
            }else{
                return out;
            }
        }*/
        /*if(nums.length==1&&nums[0]==target){
            out[0]=0;
            out[1]=0;
            return out;
        }*/

        //升序
        int left=0;
        int right=nums.length-1;
        int mid=0;
        int temL=0;
        int temR=0;
        while(left<=right){
            mid=(left+right)/2;

            if(nums[mid]==target){
                //向左寻找第一个  向右寻找最后一个
                temL=mid;
                while(0<=temL&&nums[temL]==target){
                    --temL;
                }
                out[0]=temL+1;

                temR=mid;
                while(temR<nums.length&&nums[temR]==target){
                    ++temR;
                }
                out[1]=temR-1;
            }

            if(nums[mid]<target){
                left=mid+1;
            }else{
                right=mid-1;
            }
        }

        return out;
    }
}

二分法查找原理

35搜索插入位置

这题解答一直没做全

个人的:

class Solution {
    public int searchInsert(int[] nums, int target) {
        if(nums==null) return 0;
        if(target<=nums[0]) return 0;
        if(target>nums[nums.length-1]) return nums.length;
        if(nums.length==1){
            if(target<=nums[0]) return 0;
            if(target>nums[nums.length-1]) return nums.length;
        }
        int mid=0;
        int left=0;
        int right=nums.length-1;

        while(left<right){
            mid=(left+right)/2;

            if(nums[mid]==target){
                return mid;
            }

            if(nums[mid]<target) {//在mid 和right之间
                left=mid+1;
                if(nums[left]>target){//mid<target<left
                    return left;
                }
            }else if(nums[mid]>target) {//有可能 在mid和left或者right之间。
                right=mid-1;
                if(nums[right]<target){//在right<target<mid之间
                    return mid;
                }
            }
        }

        return 0;
    }
}

官方:

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

 81,搜索旋转排序数组II

class Solution {
    public boolean search(int[] nums, int target) {
        //原本升序    
        //翻转之后以target为界升序
        //可能会有重复项
        if(nums==null) return false;
        if(nums.length==1 && nums[0]==target) return true;

        int left=0;
        int right=nums.length-1;
        int mid=0;

        while(left<=right){
           // mid=(nums[left] + nums[right])/2;
           //去重处理
           while(left<right && nums[left]==nums[left+1]) left++;
           while(left<right && nums[right]==nums[right-1]) right--;

            mid=(left+right)/2;
            if(nums[mid]==target) return true;
            if(nums[left]==target) return true;
            if(nums[right]==target) return true;

            //判断左半部分是否有序
            if(nums[left]<nums[mid]){
                //左半部分有序
                if(nums[left] <target && target <nums[mid]){
                     right=mid-1;
                }else{
                    left=mid+1;
                }//目标值在左半部分(有序)
                
            }else{
                //右半部分有序
                if(nums[mid] < target && target <nums[right]){
                     left=mid+1;
                }else{
                     right=mid-1;
                }

            }

            

            /*else{
                //右半部分有序
                if(nums[mid] < target && target <nums[right]) left=mid+1;
                if(nums[mid] < target) right=mid-1;
            }*/
        }
        return false;

    }
}
//重复的话  一部分有序的 可能都是一样的值 说明  相等也可能

微信小程序提供了日期时间选择器组件`picker`和日历组件`calendar`,但如果需要自定义样式或者功能,可以考虑封装一个日期时间组件。 以下是一个简单的日期时间组件的封装示例: 1. 在`/components`目录下创建一个`datetime-picker`文件夹,创建`datetime-picker.wxml`、`datetime-picker.wxss`、`datetime-picker.js`和`datetime-picker.json`四个文件。 2. 在`datetime-picker.json`中定义组件的属性: ```json { "component": true, "usingComponents": {}, "properties": { "startDate": { "type": String, "value": "2023-02-15", }, "endDate": { "type": String, "value": "2023-02-20", }, "startTime": { "type": String, "value": "00:00", }, "endTime": { "type": String, "value": "23:59", }, "defaultDate": { "type": String, "value": "", }, "defaultTime": { "type": String, "value": "", }, "format": { "type": String, "value": "datetime", }, "showTime": { "type": Boolean, "value": true, }, "showDate": { "type": Boolean, "value": true, }, "startPlaceholder": { "type": String, "value": "开始时间", }, "endPlaceholder": { "type": String, "value": "结束时间", }, "bind:change": { "type": Function, "value": "", } }, "options": { "styleIsolation": "apply-shared" } } ``` 上述属性中: - `startDate`和`endDate`为日期范围,用于限制可选日期的范围; - `startTime`和`endTime`为时间范围,用于限制可选时间的范围; - `defaultDate`和`defaultTime`为默认值; - `format`为显示格式,支持`datetime`、`date`和`time`三种格式; - `showTime`和`showDate`分别控制是否显示时间和日期选择器; - `startPlaceholder`和`endPlaceholder`为开始时间和结束时间的占位符; - `bind:change`为选择器值变化时的回调函数。 3. 在`datetime-picker.wxml`中定义选择器组件: ```html <view class="datetime-picker"> <view wx:if="{{showDate}}" class="datetime-picker-item"> <picker mode="date" start="{{startDate}}" end="{{endDate}}" value="{{selectedDate}}" bindchange="onDateChange"> <view class="datetime-picker-value"> <text wx:if="{{selectedDate}}">{{selectedDate}}</text> <text wx:else>{{startPlaceholder}}</text> </view> </picker> </view> <view wx:if="{{showTime}}" class="datetime-picker-item"> <picker mode="time" start="{{startTime}}" end="{{endTime}}" value="{{selectedTime}}" bindchange="onTimeChange"> <view class="datetime-picker-value"> <text wx
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值