LeetCode刷题笔记【1】:数组专题-1(二分查找,移除数组中指定元素)

文章目录

  • 前置知识
  • 704. 二分查找
    • 题目描述
    • 解题思路
      • 暴力搜索
      • 二分查找
  • 27. 移除元素
    • 题目描述
    • 解题思路
      • 暴力解决
      • 双指针交换
  • 总结

前置知识

注意数组在C++中的存储方式是在地址连续的空间中存储,所以可以通过name[n]这样的下标访问。

连续存储方便了访问,但是对于删除等操作,就需要大量移动元素,耗时较大。

C++提供了容器vetctor,也可以使用。

参考文章:https://programmercarl.com/%E6%95%B0%E7%BB%84%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html

704. 二分查找

题目描述

LeetCode链接:https://leetcode.cn/problems/binary-search/

LeetCode刷题笔记【1】:数组专题-1(二分查找,移除数组中指定元素)_第1张图片

解题思路

暴力搜索

直接遍历所有元素寻找target值

// 暴力搜索
class Solution {
public:
     int search(vector<int>& nums, int target) {
        int n=nums.size();
        for(int i=0; i<n; ++i){
            if(nums[i]==target)
                return i;
        }
        return -1;
    }
};

二分查找

暴力搜索可以实现, 但是时间空间复杂度过高, 下面尝试使用二分查找。

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int n=nums.size();
        int left=0, right=n-1;
        while(left<=right){//注意这里是<=,因为left=right的时候也是有意义的
            int middle = (left+right)/2;
            if(nums[middle]==target)
                return middle;
            if(nums[middle]<target){
                left = middle+1;
            }else{
                right = middle-1;
            }
        }
        return -1;
    }
};

27. 移除元素

题目描述

LeetCode链接:https://leetcode.cn/problems/remove-element/

LeetCode刷题笔记【1】:数组专题-1(二分查找,移除数组中指定元素)_第2张图片
LeetCode刷题笔记【1】:数组专题-1(二分查找,移除数组中指定元素)_第3张图片

解题思路

暴力解决

// 暴力法, 挨个遍历元素, 如果是val, 那就将其后面的元素依次前移
class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int n=nums.size();
        int ans=n;
        for(int i=0; i<ans; ){
            if(nums[i]==val){
                for(int j=i+1; j<ans; ++j){
                    nums[j-1] = nums[j];
                }
                --ans;
                continue;
            }
            ++i;
        }
        return ans;
    }
};

双指针交换

暴力法肯定可以解决问题, 但是本题对时间复杂度要求通不过.

因为暴力法每次遇到目标值的时候, 都需要依次操作目标值后面的所有值.

但是考虑题目有暗示我们不用删除val元素, 只需要将除了val以外的元素放在数组开头, 并且返回非val值的数量即可.

所以使用双指针法:

// 双指针交换法
// 发现原题不要求输出数组的顺序和原数组一致, 所以头尾两个指针, 头指针寻找val, 找到后和尾指针swap, 尾指针--
class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int n=nums.size();
        if(n==1){
            if(nums[0]==val)
                return 0;
            else
                return 1;
        }
        int head=0, tail=n-1, ans=n;
        while(head<=tail){
            if(nums[head]==val){
                // swap(nums[head], nums[tail]);
                nums[head] = nums[tail];
                --tail;
                --ans;
                continue;
            }
            ++head;
        }
        return ans;
    }
};

总结

刷题过程中要注意题目的要求和提示.

很多时候并不要求做到的一些点就可以不做到, 比如不要求顺序, 就可以乱序.

这样就可以使用一些乱七八糟的解法.

本文参考:
https://programmercarl.com/0704.%E4%BA%8C%E5%88%86%E6%9F%A5%E6%89%BE.html
https://programmercarl.com/0027.%E7%A7%BB%E9%99%A4%E5%85%83%E7%B4%A0.html

你可能感兴趣的:(LeetCode刷题笔记,leetcode,笔记,算法)