代码随想录算法训练营第一天| 704. 二分查找、27. 移除元素

二分查找:

题目链接:力扣

前提:数组为有序数组,且数组中无重复元素。
(一旦有重复元素,则二分法返回的元素下标不可能唯一)

二分法优势:时间复杂度O(logn)

注意要点:找到对的区间定义,可分为两种:1、左闭右闭   2、左闭右开

1. 左闭右闭:

代码随想录算法训练营第一天| 704. 二分查找、27. 移除元素_第1张图片

class Solution {
public:
   
    int search(vector& nums, int target) {

        int frontIndex = 0;
        int midIndex = 0;
        int backIndex = nums.size() - 1;   //左闭右闭区间

        while (frontIndex <= backIndex)
        {
            midIndex = (frontIndex + backIndex) / 2.0;
//          这里最好改为 midIndex = frontIndex + ((frontIndex - backIndex) / 2);
            if (nums[midIndex] < target)
                frontIndex = midIndex+1;
            else if (nums[midIndex] > target)
                backIndex = midIndex-1;
            else if (nums[midIndex] == target)
                return midIndex;
        }

        //未找到目标
        return -1;     

    }
};

时间复杂度:O(log2n), 时间复杂度:O(1)
这里使用 <= ,因为 frontIndex == backIndex在区间[frontIndex , backIndex]有意义,因为backIndex这个值我们可以在数组中取到。
该段代码中 midIndex = (frontIndex + backIndex) / 2.0;
最好改为 midIndex = frontIndex + ((frontIndex - backIndex) / 2);
这样做是为了防止溢出,
比如100是溢出。那么(60+50)/2就溢出了,因为先计算的60+50,。但是50+(60-50)/2就可以,先算60-50。

2:左闭右开:

代码随想录算法训练营第一天| 704. 二分查找、27. 移除元素_第2张图片

class Solution {
public:
   
    int search(vector& nums, int target) {

        int frontIndex = 0;
        int midIndex = 0;
        int backIndex = nums.size();   //左闭右开区间

        while (frontIndex < backIndex)
        {
            midIndex = (frontIndex + backIndex) / 2.0;
//          这里最好改为 midIndex = frontIndex + ((frontIndex - backIndex) / 2);
            if (nums[midIndex] < target)
                frontIndex = midIndex+1;
            else if (nums[midIndex] > target)
                backIndex = midIndex;
            else if (nums[midIndex] == target)
                return midIndex;
        }

        //未找到目标
        return -1;     

    }
};

时间复杂度:O(log2n), 时间复杂度:O(1)
这里使用 < ,因为 frontIndex == backIndex在区间[frontIndex , backIndex)是没有意义的,因为此时backIndex不能被取到


移除元素

题目链接:力扣

题目中要求原地修改,即只能在原数组上进行操作

知识点:双指针,掌握对快慢指针
快指针:寻找新数组里所需要的元素,不是则跳过
慢指针:新数组的下标值

class Solution {
public:
    int removeElement(vector& nums, int val) {

        int slow = 0;

        for(int fast = 0; fast < nums.size(); fast++)
        {
            if(nums[fast] != val)
            {
                nums[slow++] = nums[fast];
            }
       }
       return slow;
    }
};

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

这里,slow就等于最终移除完元素的大小。

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