LeetCode刷题之二分查找

5 篇文章 0 订阅
1 篇文章 0 订阅

69. x 的平方根

class Solution {
    //1、0问题,找到最后一个平方小于x的值
    public int mySqrt(int x) {
        double head = 0,tail = x,mid;
        for(int i = 0;i<32;i++){
            mid = head + ((tail-head)/2);
            if(mid*mid<=x)head = mid;
            else tail = mid;
        }
        return (int)head;
    }
}

35. 搜索插入位置

class Solution {
	//如果没有找到则意味着要插入在最后,所以是返回nums.length
    public int searchInsert(int[] nums, int target) {
        int head = 0,tail = nums.length-1,mid;
        while(tail - head>3){
            mid = (head+tail)>>1;
            if(nums[mid]>=target)tail = mid;
            else head = mid +1;
        }
        for(int i =  head;i<=tail;i++){
            if(nums[i]>=target)return i;
        }
        return nums.length;
    }
}

1 两数之和

class Solution {

    //对下标排序,用一个数组记录下表(套娃式搜索)
    public int[] twoSum(int[] nums, int target) {
        Integer[] arr  = new Integer[nums.length];
        for(int i = 0;i<nums.length;i++)arr[i] = i;
        Arrays.sort(arr,(i,j)->nums[i]-nums[j]);
        int[] res = new int[2];
        for(int i = 0;i<arr.length;i++){
            int val = nums[arr[i]];
            int j = binarySearch(nums,arr,i+1,target-val);
            if(j==-1)continue;
            res[0] = Math.min(arr[i],arr[j]);
            res[1] = Math.max(arr[i],arr[j]);
        }
        return res;
    }

    int binarySearch(int[] nums,Integer[] arr,int head , int x){
        int tail = arr.length -1,mid;
        while(head<=tail){
            mid = (head+tail)>>1;
            if(nums[arr[mid]]==x)return mid;
            if(nums[arr[mid]]<x)head = mid+1;
            else tail = mid-1;
        }
        return -1;
    }
}

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

class Solution {

	//找到第一位和下一个值的上一位,就是所求区间
    public int searchBinary(int[] nums, int x) {
        int head = 0,tail = nums.length-1,mid;
        while(tail-head>3){
            mid = (head+tail)>>1;
            if(nums[mid]>=x)tail = mid;
            else head= mid+1;
        }
        for(int i = head;i<= tail;i++){
            if(nums[i]>=x)return i;
        }
        return nums.length;
    }

    public int[] searchRange(int[] nums, int target) {
        int[] res = new int[2];
        res[0] = res[1] = -1;
        res[0] = searchBinary(nums,target);
        if(res[0]==nums.length||nums[res[0]]!=target){
            res[0] = res[1] = -1;
            return res;
        }
        res[1] = searchBinary(nums,target+1)-1;
        return res;
    }
}

1658. 将 x 减到 0 的最小操作数

class Solution {
    public int minOperations(int[] nums, int x) {
        int len = nums.length;
        int[] suml = new int[len+1];
        int[] sumr = new int[len+1];
        suml[0] = sumr[0] = 0;
        for(int i=0;i<len;i++){
            suml[i+1] = suml[i]+nums[i];
            sumr[i+1] = sumr[i]+nums[len-i-1];
        }
        int ans = -1;
        for(int i = 0;i<len+1;i++){
            int j = binarySearch(sumr,x-suml[i]);
            if(j==-1)continue;
            if(i+j>len)continue;
            if(ans==-1||ans>i+j)ans = i+j;
        }
        return ans;
    }

    int binarySearch(int[] arr,int x){
        int head = 0,tail = arr.length-1,mid;
        while(head<=tail){
            mid=(head+tail)>>1;
            if(arr[mid]==x)return mid;
            if(arr[mid]<x)head = mid+1;
            else tail = mid-1;
        }
        return -1;
    }
}

475. 供暖器

class Solution {

    //找到距离供暖器距离最远的房间的距离,相当于找第一个大于等于房间位置的供暖器
    public int findRadius(int[] houses, int[] heaters) {
        Arrays.sort(heaters);
        int ans = 0;
        for(int i:houses){
            int j = binarySearch(heaters,i);
            int a = Math.abs(heaters[j]-i);
            int b = j>0?i - heaters[j-1]:a+1;
            ans = Math.max(ans,Math.min(a,b));
        }
        return ans;
    }

    int binarySearch(int[] arr,int x){
        int head = 0,tail = arr.length-1,mid;
        while(head<tail){
            mid = (head+tail)>>1;
            if(arr[mid]>=x)tail = mid;
            else head = mid+1;
        }
        return head;
    }

}

33. 搜索旋转排序数组

class Solution {
    public int search(int[] nums, int target) {
        int head = 0,tail = nums.length-1,mid;
        while(head<=tail){
            mid = (head+tail)>>1;
            if(nums[mid]==target)return mid;
            if(nums[mid]<nums[tail]){
                if(target<=nums[tail]&&target>nums[mid])head = mid+1;
                else tail = mid-1;
            }else{
                if(target<nums[mid]&&target>=nums[head])tail = mid-1;
                else head = mid+1;
            }
        }
        return -1;
    }
}

81. 搜索旋转排序数组 II

class Solution {
	//先排除首尾相等的情况,确保尾部比头部小
	//后循进行两层if-else判断
    public boolean search(int[] nums, int target) {
        if(nums[0]==target||nums[nums.length-1]==target)return true;
        int l = 0,r = nums.length-1;
        while(l<nums.length&&nums[l]==nums[0])++l;
        while(r>=0&&nums[r]==nums[0])--r;
        int head = l,tail = r,mid;
        while(l<=r){
            mid = (l+r)>>1;
            if(nums[mid]==target)return true;
            if(nums[mid]<=nums[tail]){
                if(target<=nums[tail]&&target>nums[mid])l = mid+1;
                else r = mid-1;
            }else{
                if(target<nums[mid]&&target>=nums[head]) r = mid-1;
                else l = mid+1;
            }
        }
        return false;
    }
}

4. 寻找两个正序数组的中位数

//两个数组a,b判断a[k/2]和b[k/2]如果a[k/2]<b[k/2]那么a数组的前k/2元素都小于合并后的中位数,可以去除,取出后则开始找剩余的k/2元素。

class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int n = nums1.length,m = nums2.length,mid = (n+m+1)/2;
        double a = findK(nums1,nums2,0,0,mid);
        if((n+m)%2==1)return a;
        double b = findK(nums1,nums2,0,0,mid+1);
        return (a+b)/2.0;
    }

    double findK(int[] nums1,int[] nums2,int i,int j,int k){
        if(i == nums1.length)return nums2[j+k-1];
        if(j == nums2.length)return nums1[i+k-1];
        if(k==1)return nums1[i]<nums2[j]?nums1[i]:nums2[j];
        int a = Math.min(k/2,nums1.length - i);
        int b = Math.min(k-a,nums2.length - j);
        a = k - b;
        if(nums1[i+a-1]<=nums2[j+b-1]){
            return findK(nums1,nums2,i+a,j,k-a);
        }
        return findK(nums1,nums2,i,j+b,k-b);
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据引用\[1\]和引用\[2\]的内容,推荐的LeetCode刷题顺序是按照题目类型刷题,优先选择树、链表、二分查找、DFS、BFS、动态规划等常见类型的题目。可以先做2~4道简单题,然后再做中等难度的题目。在选择题目时,可以优先选择题目序号小、点赞多、提交成功率高的题目,这样可以从简单入手,节省时间。同时,LeetCode每道题目都有“模拟面”功能,可以给自己设定时间限制,如果做不出来可以看答案,然后记住思路后再自己尝一遍。每种类型的题目做完10+道后,可以总结规律。 根据引用\[3\]的内容,题目可以按照不同的分类进行刷题,比如数组与贪心算法、子数组与贪心算法、子序列与贪心算法、数字与贪心、单调栈法、双指针法等。可以根据自己的兴趣和需求选择相应的题目进行刷题。 综上所述,LeetCode刷题顺序可以按照题目类型或者题目分类进行选择。 #### 引用[.reference_title] - *1* [LeetCode 刷题顺序,按标签分类,科学刷题!](https://blog.csdn.net/fengyuyeguirenenen/article/details/125099023)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [leetcode 刷题指南 & 刷题顺序](https://blog.csdn.net/qijingpei/article/details/125561071)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [leetcode-刷题顺序推荐](https://blog.csdn.net/weixin_38087674/article/details/114107841)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值