代码随想录训练营day1

本文介绍了数组的基础知识,包括数组的定义、内存特性、C++中vector与数组的区别,以及二维数组的工作原理。此外,还详细讲解了二分查找算法的两种实现方式(左闭右闭和左闭右开),以及移除元素的暴力解法和双重指针优化方法。
摘要由CSDN通过智能技术生成

终于考完试了,晚了一天参加打卡,代码随想录第一天的内容是了解一下数组的定义知识点,以及完成两道入门级别的题目:二分查找和移除元素

一:数组基础知识点

我们现在先来根据代码随想录当中的内容先看看数组的基本定义和要注意的知识点是什么:

  • 数组在内存空间当中是连续的,总而言之就是存放在连续内存空间的相同数据类型的集合
  • 数组的下标是从0开始的,可以通过下标很方便地访问元素
  • 正是因为数组的内存空间是连续的,所以我们在增删数组的元素的时候,我们就必须要考虑数组当中其他元素
  • 我们有些时候在使用c++的vector容器的时候,我们会发现vector容器操作很方便,例如可以push......但是我们在这里要记住vector和array的联系和区别,vector底层实现是arrary,但是vector实际上是容器,不是数组
  • 数组的元素不能删除,只能覆盖
  • 这里还有一个很重要的问题:二维数组是怎么形成的,二维数组的内存空间是连续的吗?现在我们来好好研究一下

    例如我们先来运行下下面这段代码:
    #include<iostream>
    using namespace std;
    void print() {
    	int array[3][3] = {
    		{1,2,3},
    		{4,5,6}
    	};
    	cout << &array[0][0] << " " << &array[0][1] <<" " << &array[0][2] << endl;
    	cout << &array[1][0] << " " << &array[1][1] << " " << &array[1][2] << endl;
    }
    
    int main() {
    	print();
    	return 0;
    }

    我们这个时候就会发现C++当中二维数组其实是连续的内存空间的,每个元素的地址都相差了四个字节

二:二分查找(训练营正式开始咯,正式开始刷题啦,嘻嘻嘻!!!)

二分搜索法可以看carl大佬的bilibili视频

carl的二分搜索法视频

在leetcode的第704道题就是二分搜索法

2.1左闭右闭的写法

首先我们在这里就是要明白,因为是左闭右闭区间,所以根据区间的合法性,我们是可以直接使用while(left<=right)来进行循环判断的,并且如果nums[middle]!=target,可以直接left=middle+1或者right=middle-1;                                       

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int left=0;
        int right=nums.size()-1;//在这里的左闭右闭
        int middle=0;//定义middle用于定义left和right中间的值
        while(left<=right){  //左闭右闭支持两端相等
            middle=(left+right)/2;
            if(nums[middle]==target){
                return middle;
            }else if(nums[middle]>target){
                right=middle-1;
            }else if(nums[middle]<target){
                left=middle+1;
            }

        }
        return -1;
    }
};
2.2左闭右开的写法 

因为是左闭右开,所以一开始的right的值就要取right=nums.size(),并且当nums[middle]>target的时候,right=middle而不是=middle-1

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

三、移除元素

3.1暴力解法:

使用双重for循环进行暴力解题:

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int length=nums.size();
        for(int i=0;i<length;i++){
            if(nums[i]==val){
                for(int j=i+1;j<length;j++){
                    nums[j-1]=nums[j];
                }
                i--;
                length--;
            }

        }
        return length;
    }
};
3.2双重指针进行运算

双重指针进行for循环,一下子就把我们前面说的那种暴力解法替代了

在这里我们需要先了解一下slow慢指针和fast快指针的作用,fast指针用来获取遍历原来数组当中的元素,slow慢指针用来给新数组赋值,不断更新新数组当中的元素

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

  • 25
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值