代码随想录算法训练营DAY1 | 704、27

本文详细介绍了二分查找算法在不同LeetCode问题中的应用,包括搜索目标值、插入位置查找以及在排序数组中查找重复元素。同时提及了优化方法和相关的时间复杂度分析。
摘要由CSDN通过智能技术生成

704.二分查找 

题目链接:704. 二分查找 - 力扣(LeetCode)

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){
                return mid;
            }else if(nums[mid]>target){
                right=mid-1;
            }else if(nums[mid]<target){
                left=mid+1;
            }
        }
        return -1;
    }
}

注意:指针所指区间为左闭右闭区间,故循环终止条件为left>right。与mid所指元素比较后,右指针要-1。循环结束后仍未找到,返回-1。

可以优化的地方:mid=left+(right-left)/2,防止溢出。

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){
                return mid;
            }else if(nums[mid]>target){
                right=mid;
            }else if(nums[mid]<target){
                left=mid+1;
            }
        }
        return -1;
    }
}

35.搜索插入位置

题目链接:

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

二分查找后的left即是应该插入的位置

34.在排序数组查找重复元素的索引

题目链接:34. 在排序数组中查找元素的第一个和最后一个位置 - 力扣(LeetCode)

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

 时间复杂度为O(logn+n)。

简化

class Solution {
    public int[] searchRange(int[] nums, int target) {
        // 利用二分查找函数
        int leftIdx=binarySearch(nums,target,true);
        int rightIdx=binarySearch(nums,target,false)-1;
        if(leftIdx<=rightIdx&&rightIdx<nums.length&&nums[leftIdx]==target&&nums[rightIdx]==target){
            return new int[]{leftIdx,rightIdx};
        }
        return new int[]{-1,-1};
    }
    public int binarySearch(int[] nums,int target,boolean lower){
        // ans在leftidx第一个等于target的数,在right中第一个不等于的索引
        int left=0,right=nums.length-1,ans=nums.length;
        while(left<=right){
            int mid=left+(right-left)/2;
            if(nums[mid]>target||(lower&&nums[mid]>=target)){
                right=mid-1;
                ans=mid;
            }else{
                left=mid+1;
            }
        }
        return ans;
   }
}

27.移除元素

题目链接:27. 移除元素 - 力扣(LeetCode)

class Solution {
    public int removeElement(int[] nums, int val) {
        // 快慢指针
        int slow=0,fast=0;
        while(fast<nums.length){
            if(nums[fast]!=val){
                nums[slow]=nums[fast];
                slow++;
            }
            fast++;
        }
        return slow;
    }
}

心得:利用快慢指针。之后考虑什么时候移动慢指针、快指针、循环结束条件。

循环结束条件:fast要遍历数组所有元素。

移动快指针:每循环一次fast++。

移动慢指针:当快指针所指元素不是val时,将该元素移动到slow指针上,slow++。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值