DAY1--二分查找,双指针,704,34,35,27

写在开头,三月份开始陆续刷了代码随想录到动态规划,三天打鱼两天晒网,有时状态好一天快10道,懒惰时一个礼拜刷不了一个,不得行,做笔试题做的想鼠,我只是可怜的鼠鼠,下定决心,要每天跟着进度走,我这勉强算二刷,也是看到题大概有个思路,冲!

ps:我是自己做了一个文档,记得比较详细(题目和解析),这就当一个打卡的地方,只放思路和解析代码,今天整了老半天怎么在idea里刷题,推送到仓库里,还不是很熟练,明天试试看。

704:二分查找

思路:二分法是没问题的,也能想出来用while循环,但每次while循环里的条件都会写反,每一次,之前是反转链表输出,循环条件直接写了空根本没进去,习惯用左闭右开,但是边界还是有问题,返回去看一遍解析就能写对。

题目注意:给的是升序数组(有顺序),数组里元素不重复。

代码如下(左闭右开):

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

左闭右闭:

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

 要注意最开始右边开的话初始值为数组长度-1.

35  搜索插入位置

二分法:能找到的话就返回mid值,要是没找到的话返回right值,因为要是没找到,插入的位置肯定是最右边的下一个。

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

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

思路:左闭右闭会比较好做一些。一个找到左边的端点,另一个找右边。精髓在于相等时一个不断左移,一个不断右移。

public int[] searchRange(int[] nums, int target) {
        int left=0;
        int length=nums.length;
        int right=length-1;
        int first=-1;
        int last=-1;
        while(left<=right){
            int mid=(left+right)/2;
            if(nums[mid]==target){
                first=mid;
                right=mid-1;//zhongdian
            }else if(nums[mid]>target){
                right=mid-1;
            }else{
                left=mid+1;
            }
        }
        left=0;
        right=length-1;
        while(left<=right){
            int mid=(left+right)/2;
            if(nums[mid]==target){
                last=mid;
                left=mid+1;//zhongdian
            }else if(nums[mid]>target){
                right=mid-1;
            }else{
                left=mid+1;
            }
        }
        return new int[]{first,last};
    }

 27. 移除元素

双指针忘记怎么实现了,暴力法是想新建一个数组,循环遍历原先的数组,遇到指定值就计数+1,不是指定值挪到新数组,这样问题是新数组会有空值出现,测评时也不符合要求,得再遍历一遍新数组,增强for写错了。。no,错了,数组初始化时会全为0,这样怎么判断是初始化的0还是之前数组里的0。

根据解题方法里写的暴力法提示我提交出错,原因不明。

public int removeElement(int[] nums, int val) {
        int size=nums.length;
        for(int i=0;i<nums.length;i++){
            if(nums[i]==val){
                for(int j=i+1;j<size;j++){
                    nums[j-1]=nums[j];
                }
                i--;
                size--;
            }
        }
        return size;
    }

双指针法:通过快慢两个指针在一个for循环下完成两个for循环的任务

快指针:在旧数组寻找新数组的元素。

慢指针:更新新数组的下标。

public int removeElement(int[] nums, int val) {
        int slow=0;
        for(int fast=0;fast<nums.length;fast++){
            if(nums[fast]!=val){
              nums[slow]=nums[fast];
              slow++;
            }
        }
        return slow;
    }

 解析里的动图对做题理解真的很有帮助,外层的快指针是一定会把整个旧数组都遍历到的,里面则是有了可以放进新数组的元素,放进去慢指针++。

  • 9
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值