704.二分法查找下标|27.拔萝卜法移除数组元素

1,334 阅读2分钟

704.二分查找下标

给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target  ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。

输入: nums = [-1,0,3,5,9,12], target = 9
输出: 4

区间的定义就是不变量。要在二分查找的过程中,保持不变量,就是在while寻找中每一次边界的处理都要坚持根据区间的定义来操作,这就是循环不变量规则。

👉🏻通过midtarget的位置关系缩小leftright的区间,最终使mid指向target
👉🏻确定区间,使用[left,right]还是[left,right)
👉🏻为什么要 mid=left+(right-left) / 2 : 因为当 (left+right)/2 时,left+right如果取到最大就超过了int范围

class Solution {
    public int search(int[] nums, int target) {
        if (target < nums[0] || target > nums[nums.length-1]){
            return -1;
        }
        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;
    }
}

27.移除元素

给你一个数组 nums 和一个值 val,你需要原地移除所有数值等于val的元素,并返回移除后数组的新长度。

输入: nums = [3,2,2,3], val = 3
输出: 2, nums = [2,2]

数组的元素在内存地址中是连续的,不能单独删除数组中的某个元素,只能覆盖。

👉🏻快指针遍历,慢指针指向非val
一堆萝卜连续种在地里,现在要将名字叫val的萝卜拔出,为保证连续,后面的萝卜要把val留下的坑补上。slow指向萝卜坑,fast负责依次寻找,每当坑和萝卜配对成功时slow就指向下一个坑,遇到val就把后一个不是val的萝卜放进val留下的坑里

class Solution {
    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;
    }
}

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 1 天,点击查看活动详情