【代码随想录刷题】Day01 数组

1. 704二分查找

1.1数组理论基础

  • 数组的存储:数组是存放在连续内存空间上的相同类型数据的集合。数组下标都是从0开始的。

  • 数组的元素是不能删的,只能覆盖。

    例如:删除下标为3的元素,需要对下标为3的元素后面的所有元素都要做移动操作,如图所示:
    【代码随想录刷题】Day01 数组_第1张图片

1.2 解题思路

这道题目的前提是有序数组且数组中无重复元素

mid避免越界:mid=left+((right-left)>>1);

关键点:区间的定义

  • 左闭右闭:target在[left,right]中间
    • while (left <= right) 要使用 <= ,因为left == right是有意义的,所以使用 <=
    • if (nums[mid] > target) right 要赋值为 mid - 1,因为当前这个nums[mid]一定不是target,那么接下来要查找的左区间结束下标位置就是 mid - 1
class Solution {
    public int search(int[] nums, int target) {
        int left=0;
        int right=nums.length-1;
        while (left<=right){
            int mid=left+((right-left)>>1);
            if (nums[mid]== target){
                return mid;
            }else if (nums[mid]<target){
                left=mid+1;
            }else if (nums[mid]>target){
                right=mid-1;
            }
        }
        return -1;
    }
}
//时间复杂度:O(log n)
//空间复杂度:O(1)
  • 左闭右开:target在[left,right)中间
    • while (left < right),这里使用 < ,因为left == right在区间[left, right)是没有意义的
    • if (nums[mid] > target) right = middle,因为当前nums[mid]不等于target,去左区间继续寻找,而寻找区间是左闭右开区间,所以right=middle,即:下一个查询区间不会去比较nums[mid]
class Solution {
    public int search(int[] nums, int target) {
        int left=0;
        int right=nums.length;
        while (left < right){
            int mid=left+((right-left)>>1);
            if (nums[mid]== target){
                return mid;
            }else if (nums[mid]<target){
                left=mid+1;
            }else if (nums[mid]>target){
                right=mid;
            }
        }
        return -1;
    }
}
//时间复杂度:O(log n)
//空间复杂度:O(1)

2. 27移除元素

双指针法(快慢指针法):通过一个快指针和慢指针在一个for循环下完成两个for循环的工作

定义快慢指针

  • 快指针:寻找新数组的元素 ,新数组就是不含有目标元素的数组
  • 慢指针:指向更新 新数组下标的位置

第一次使用这个方法有点懵(卡哥超详细讲解视频:数组中移除元素并不容易! | LeetCode:27. 移除元素_哔哩哔哩_bilibili)

class Solution {
    public int removeElement(int[] nums, int val) {
        int left=0;
        int right=nums.length-1;
        while (right >=0 && nums[right] ==val){
            right--;
        }
        while (left<=right){
            if(nums[left]==val){//left位置的元素需要移除
                //将right位置的元素移到left位置(覆盖),right位置移除
                nums[left]=nums[right];
                right--;
                
            }
            left++;
            while (right>=0 &&nums[right]==val){
                right--;
            }
        }
        return left;

    }
}
//使用场景:比如原本需要2次遍历才能完成移除元素,你一前一后双指针直接一次遍历完成了,这就是双指针的好处,减少重复遍历

你可能感兴趣的:(代码随想录刷题,leetcode,算法,数据结构)