代码随想录算法训练营第1天 | 数组二分法、数组双指针

二分法
2024年7月3日

重点是理解左闭右开和左闭右闭的选择对middle±1的影响。如果判断过了,下一次循环就不应该包含这个边界。

易错

  • 注意计算mid的方式,直接求均值的错误方式会超出上界。
  • 不是mid和target比较而是nums[mid]

题704. 二分查找

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

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

题35. 搜索插入位置

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

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

class Solution {
        public int[] searchRange(int[] nums, int target) {
        int left=0,right=nums.length-1;
        int mid=0;
        int r1=-1,r2=-1;
        while(left<=right){
            mid = left+(right-left)/2;
            if(nums[mid]>target){
                right = mid-1;    
            }else if(nums[mid]<target){
                left = mid+1;
            }else{
                r1=mid;
                right=mid-1;//继续往左尝试
            }
        }
        left=0;
        right=nums.length-1;
        while(left<=right){
            mid = left+(right-left)/2;
            if(nums[mid]>target){
                right = mid-1;    
            }else if(nums[mid]<target){
                left = mid+1;
            }else{
                r2=mid;
                left=mid+1;//继续往右尝试
            }
        }
        return new int[]{r1,r2};
    }
}

题69. x 的平方根

class Solution {
    public int mySqrt(int x) {
        int left=0,right=x;
        int mid=0,res=-1;
        while(left<=right){
            mid = left+(right-left)/2;
            if((long)mid*mid<x){//注意必须转long防止int*int溢出
                res=mid;
                left=mid+1;
            }
            else if((long)mid*mid>x){
                right=mid-1;
            }else{
                return mid;
            }
        }
        return res;
    }
}

题367. 有效的完全平方数

class Solution {
    public boolean isPerfectSquare(int x) {
        int left=0,right=x;
        int mid=0,res=-1;
        while(left<=right){
            mid = left+(right-left)/2;
            if((long)mid*mid<x){//注意必须转long防止int*int溢出
                res=mid;
                left=mid+1;
            }
            else if((long)mid*mid>x){
                right=mid-1;
            }else{
                return true;
            }
        }
        return false;
    }
}

移除数组元素
使用快慢指针。快指针遍历,遇到符合需求的,用慢指针给数组赋值。

注意

  • 遍历范围为快指针直到数组末尾;
  • 不管是不是同一位置,统一将快指针数值复制到慢指针;
  • 如果不符合要求,慢指针不动,快指针进1;
  • 如果符合要求,先复制值,再统一进1。

题27. 移除元素

class Solution {
    public int removeElement(int[] nums, int val) {
        int left=0,right=0;
        for(;right<nums.length;){
            if(nums[right]!=val){
                nums[left] = nums[right];
                left+=1;//赋了有效值才右移
            }
            right+=1;//每一次都右移
        }
        return left;
    }
}

题26. 删除排序数组中的重复项

class Solution {
    public int removeDuplicates(int[] nums) {
        HashSet<Integer> set1 = new HashSet<>();
        int r1 = 0,r2=0;
        for(;r2<nums.length;){
            if(!set1.contains(nums[r2])){
                set1.add(nums[r2]);
                nums[r1] = nums[r2];
                r1+=1;
            }
            r2+=1;
        }
        return set1.size();
    }
}
posted @ 2024-07-03 21:26  hailicy  阅读(169)  评论(0编辑  收藏  举报