代码随想录第1天|数组

704.二分查找

题目

思路:二分查找
使用条件:连续数组,且数组有序
备注:注意处理边界问题

左闭右闭合的方法


27. 移除元素

题目

知识点:

  1. vector的底层机制用的还是array数组实现
  2. vector没有对内存进行操作,使用size变量做计数器
  3. erase的复杂度为O(n)

思路:

  • 直接调用earse库
  • 拷贝再重新赋值 空间复杂度不允许
  • 两次for暴力解法

快慢指针实现
请添加图片描述


以下为相关题目
涉及二分法
35.搜索插入位置(opens new window)
34.在排序数组中查找元素的第一个和最后一个位置(opens new window)
69.x 的平方根(opens new window)
367.有效的完全平方数
涉及滑动窗口
26.删除排序数组中的重复项(opens new window)
283.移动零(opens new window)
844.比较含退格的字符串(opens new window)
977.有序数组的平方


35. 搜索插入位置

思路:二分查找
状态:没做出来
原因:

  1. 返回值没有分清,当未找到位置时,错误使用mid作为判断返回
  2. nums[mid] < target 时,应该移动 Left
  3. target < nums[mid] 时,应该移动 Right
  4. 需要明确若失败后,其Left和Right的位置应该是怎样的
  5. 根据结果可知需要返回 R+1 或者返回 L

插入失败时L和R的情况

当插入失败时L和R的结果
class Solution {
public:
    int searchInsert(vector<int>& nums, int target) {
        int l = 0, r = nums.size() - 1;
        int mid;
        while (l <= r) {
            mid = (l + r) / 2;
            if (nums[mid] < target) {
                l = mid + 1;
            } else if (nums[mid] > target) {
                r = mid - 1;
            } else {
                return mid;
            }
        }
        return r + 1;
    }
};

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

给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。

如果数组中不存在目标值 target,返回 [-1, -1]

你必须设计并实现时间复杂度为 O(log n) 的算法解决此问题。
在这里插入图片描述
思路:二分法,需要对其做出些调整
比如在寻找到元素时,可以更新边界,其它情况照旧

class Solution {
public:
    int find_left(vector<int>& nums, int target) {
        int l = 0, r = nums.size() - 1;
        int result = -1;
        while (l <= r) {
            int mid = (l + r) / 2;
            if (target > nums[mid]) {
                l = mid + 1;
            } else if (target < nums[mid]) {
                r = mid - 1;
            } else {
                result = mid;
                r = mid - 1;
            }
        }
        return result;
    }
    int find_right(vector<int>& nums, int target) {
        int l = 0, r = nums.size() - 1;
        int result = -1;
        while (l <= r) {
            int mid = (l + r) / 2;
            if (target > nums[mid]) {
                l = mid + 1;
            } else if (target < nums[mid]) {
                r = mid - 1;
            } else {	//当寻找到目标值时,设当前的值为边界,再往右移动尝试,判断右一个元素是否为边界值
                result = mid;
                l = mid + 1;
            }
        }
        return result;
    }
    vector<int> searchRange(vector<int>& nums, int target) {
        int left = find_left(nums, target);
        int right = find_right(nums, target);
        if (left < 0 && right < 0)
            return {-1, -1};
        else
            return {left, right};
    }
};

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

在这里插入图片描述
在这里插入图片描述
思路:双指针法实现

//需优化,此部分判断是否重复出现问题
//官方题解直接判断slow-1是否和fast相同
class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        int fast = 1, slow = 1;
        int flag = nums[0];
        int size = nums.size();
        if (nums.size() == 1) return 1;

        for (; fast < nums.size(); fast++) {
            if (nums[fast] == flag) {
                size--;
                continue;
            } else {
                nums[slow++] = nums[fast];
                flag = nums[fast];
            }
        }
        return size;
    }
};

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值