算法打卡Day1|704二分查找&& 27移除元素

二分查找

题目类型:

在【有序】且【无重复元素】的数组中,找到target元素下标

思路:

一分为二,middle>target,区间右边缩小;middle<target,区间左边变大

注意点:

  • 两个int相加可能会越界
  • 根据区间定义决定right/left写法,middl小于target时候,两种方法left更新都是middle+1
    • 左闭右闭[left,right] , left=right是合法的->while(left<=right),** right减,大的减,小的加 **

      int right = nums.size() - 1; // 定义target在左闭右闭的区间里,[left, right]
           while (left <= right) { // 当left==right,区间[left, right]依然有效,所以用 <=
               int middle = left + ((right - left) / 2);// 防止溢出 等同于(left + right)/2
               if (nums[middle] > target) {
                   right = middle - 1; // target 在左区间,所以[left, middle - 1]
               } else if (nums[middle] < target) {
                   left = middle + 1; // target 在右区间,所以[middle + 1, right]
               } else { // nums[middle] == target
                   return middle; // 数组中找到目标值,直接返回下标
               }
               ```
      
      
    • 左闭右开[left,right) ,** right不变,大不变,小的加**

      int right = nums.size(); 
      while (left < right) { // 因为left == right的时候,在[left, right)是无效的空间,所以使用 <
           int middle = left + ((right - left) >> 1);
           if (nums[middle] > target) {
               right = middle; // target 在左区间,在[left, middle)中
           } else if (nums[middle] < target) {
               left = middle + 1; // target 在右区间,在[middle + 1, right)中
           } else { // nums[middle] == target
               return middle; // 数组中找到目标值,直接返回下标
           } ```
      
      

代码示例

C++

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int left =0;
        int right = nums.size()-1;
        while(left<=right){
            int middle=left+((right-left)/2);
            if(nums[middle]>target){
                right=middle-1;
            }
            else if(nums[middle]<target){
                left=middle+1;
            }
            else{
                return middle;
            }
        }
        return -1;

    }
};

python

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        left=0
        right=len(nums)-1
        while left<=right:
            middle=left+(right-left)//2
            if nums[middle] > target:
                right=middle-1
            elif nums[middle] < target:
                left=middle+1
            else:
                return middle
        return -1

移除元素

题目类型

给数组,给目标值,删除目标值,返回新数组的长度

思路

  • 库函数 erase() 时间复杂度O(n)
  • 双循环
  • 双指针:快慢指针,快指针指向新数据所需元素,新数组下标是slow指针 ,相当于** 把不是target的元素全部提出到另一个数组nums[slow]中**
    这题解法的核心就是遍历数据过程中遇到等于目标值就直接跳过,不等于目标值就赋值,这样就能 过滤掉(也就是删除掉)目标值

注意点

慢指针使用了要+1

代码示例

双指针重建新数组nums[slow],把不是target的都放到新数组中

C++写法

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int slow =0;
        for(int fast =0;fast<nums.size();fast++){
            if(nums[fast]!=val){
                nums[slow]=nums[fast];
                slow++;
            }
        }
        return slow;

    }
};

python 写法

    def removeElement(self, nums: List[int], val: int) -> int:
        fast=0
        slow=0
        size=len(nums)
        for fast in range(size):
            if nums[fast]!=val:
                nums[slow]=nums[fast]
                slow+=1
         
        return slow  

收获总结

双指针法(快慢指针法)在数组和链表的操作中是非常常见的,很多考察数组、链表、字符串等操作的面试题,都使用双指针法
有环:快慢指针定会相遇

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值