【攻克剑指offer】第5天《在排序数组中查找数字》


题目描述: 💦
在这里插入图片描述
👉题目链接👈

🏠解法一、暴力求解

思路分析: 💫

相比说到暴力求解多少都有点思路了,直接遍历数组,一个一个找相同的数,然后统计总数。

代码展示: 👇

class Solution {
    public int search(int[] nums, int target) {
        int count = 0;

 //for(数据类型 变量名 :集合对象名)  
        for(int x : nums){     //我这里遍历数组简写了 习惯了for-each循环
            if(x == target){
               count ++;   //统计总数
            }
        }
        return count;
    }
}

以上算法实现的复杂度分析:

  • 时间复杂度是: O(n)
  • 空间复杂度是 : O(1)

🏠解法二、二分法

重新审题看细节:

统计一个排序数组,看到排序(顺序)第一个反应就是“二分法”,所以这道题真正考验的就是你每次都能做对的二分法了(滑稽)

在这里插入图片描述

代码展示: 👇

//利用两次二分法分别确定target的左右边界(左右边界为target值序列的左/右一位,因此最终结果是right-left-1)
class Solution {
    public int search(int[] nums, int target) {
        if(nums.length == 0) {
            return 0;
        }
        //初始左右指针位置
        int i = 0;
        int j = nums.length-1;
        //第一次二分:找right边界
        //这边是“小于等于”,因此当循环结束后,ij不重合,且如果存在target值的话,i的位置就是右边界(target值序列右边第一个大于target值的位置),因为最后一次循环一定是i=mid+1;且此时j指向target
        while(i <= j) {
            int mid = (i+j) >> 1;
            //这里是“小于等于”,目的是为了确定右边界,就是说当mid等于target时,因为不确定后面还有没有target,所以同样需要左边收缩范围
            if(nums[mid] <= target){
                i = mid+1;
            }
            else{
                j = mid-1;
            }
        }
        //在更新right边界值之前,需要判断这个数组中是否存在target,如果不存在(看j指向的位置是不是target,为什么看的是j指针?详见上面的注释)
        if(j>=0&&nums[j] != target){
            return 0;
        }
        int right = i;    //更新right边界
        //重置指针
        i = 0;
        j = nums.length-1;
        //第二次二分:找left边界
        //结束之后,j指向target序列左边第一个小于它的位置,i指向target(经过上面判断,target一定存在)
        while(i <= j) {
            int mid = (i + j) >> 1;
            //这里是“大于等于”,目的是确定左边界,因为就算当mid等于target的时候,因为不确定左边还有没有target,所以同样需要收缩右边界
            if (nums[mid] >= target) {
                j = mid - 1;
            } else {
                i = mid + 1;
            }
        }
        //更新左指针
        int left = j;
        return right-left-1;
    }
}

图解:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

以上算法实现的复杂度分析:

  • 时间复杂度是:O(logN) :二分法为对数级别复杂度。
  • 空间复杂度是 : O(1): 几个变量使用常数大小的额外空间。

相关文章:
上一篇:【剑指offer】之《在排序数组中查找数字》

🌈我的感受:

  二分法没有看晕吧,我也不想二分的,但是这题它考的就是二分,怎么说也要配合一下,其实熟悉掌握了二分原理其实这类题是有思路的固定模式差不多,主要是写代码时要细心分析好临界点慢慢来不着急。最近在学算法更新会慢些,还有就是明天打个小比赛,又可以体会到属于夏天的美好了😄(我可不是想看妹子)
在这里插入图片描述

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小奕vi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值