力扣刷题之数组(1) | 704. 二分查找、27. 移除元素

Leetcode 704. 二分查找

题目链接

思路

根据题目中给出的数组为有序数组,并且数组中无重复元素,所以联想到使用二分法

注意点

一旦有重复元素,使用二分查找法返回的元素下标可能不是唯一的。

难点

写二分法,区间的定义一般为两种:

  • 左闭右闭[left, right]
  • 左闭右开即[left, right)
    要搞清楚区间的定义,在写代码时对mid的控制都是不同的。

代码(Java)

写法1:左闭右闭[left, right]

class Solution {
    public int search(int[] nums, int target) {
 		int left=0,right=nums.length-1;
        while (left<=right){
         //左闭右闭,所以while循环里left<=right,target在[left, right]里
            int mid = left+(right-left)/2;//防止溢出
            if (nums[mid]==target)
                return mid;
            else if (nums[mid]<target)
                left=mid+1;
            else if (nums[mid]>target)
                right=mid-1;
        }
        return -1;
}

写法2:左闭右开[left, right)

class Solution {
    public int search(int[] nums, int target) {
        int left=0,right=nums.length;
        //与写法1不同,此时right定义变成了nums.length
        while (left<right){
         //左闭右开,所以while循环里left<right,target在[left, right)里
            int mid=left+(right-left)/2;//防止溢出
            if (target==nums[mid])
                return mid;
            if (target<nums[mid])
                right=mid;
               //此时target位于中间值左侧,所以去左区间继续查找,因为右区间为开区间,right更新为mid。
            if (target>nums[mid])
                left=mid+1;
        }
        return -1;
    }
}

代码随想录链接

下面是代码随想录的文章链接与视频链接,帮助大家更好地理解这道题。
文章
视频

Leetcode 27. 移除元素

题目链接

思路

由于数组的元素在内存地址中是连续的不能单独删除数组中的某个元素,只能覆盖
可以采用暴力解法,两个for循环嵌套,一层for循环遍历数组元素,另一层for循环筛选需要的元素。
两个for循环,也可以用双指针法来解决,分别用两个指针和一个for循环完成。

难点

理解快指针慢指针各自的任务

快指针:寻找新数组的元素 ,新数组不含有目标元素的数组,找到新元素后反馈给慢指针

慢指针:指向新数组下标的位置

代码(Java)

写法1:暴力解法

时间复杂度:O(n^2)
空间复杂度:O(1)

clas Solution {
    public int removeElement(int[] nums, int val) {
        int len = nums.length;
        for (int i = 0; i < len; i++) {//外层循环:遍历数组
            if (nums[i] == val) { // 发现需要移除的元素,就将数组集体向前移动一位
                for (int j = i + 1; j < len; j++) {//内层循环:筛选数组
                    nums[j - 1] = nums[j];//将后面的元素向前移
                }
                i--; // 因为下标i以后的数值都向前移动了一位,所以i也向前移动一位
                len--; // 此时数组的大小-1
            }
        }
        return len;
    }
}

写法2:双指针法

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

class Solution {
    public int removeElement(int[] nums, int val) {
        int slow=0;
        int fast;
        for (fast=0;fast<nums.length;fast++){
            if (nums[fast]!=val)
                nums[slow++]=nums[fast];
                //快指针将需要的元素下标传递给慢指针后,慢指针向后移动1位
        }
        return slow;
        //慢指针完成最后一次更新数组后,最后一个元素的下标+1,此时慢指针的值就是数组长度
    }
}

代码随想录链接

下面是代码随想录的文章链接与视频链接,帮助大家更好地理解这道题。
文章
视频

总结

今天主要学习了二分法快慢指针的解法,
二分法中本人更倾向左闭右闭的情况,相较于左闭右开的情况更好理解mid如何更新赋值。
快慢指针中难点在于如何理解两个指针各自的任务是什么,建议多画草图,一步步理解。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Fuego91

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

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

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

打赏作者

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

抵扣说明:

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

余额充值