当前位置: 首页 > news >正文

day01 - 数组part01

一、数组基础知识

在C++中,数组在逻辑和物理空间中均是线性连续的,其元素下标从0开始。常见数组的操作:

  • 双指针 (快慢指针)
  • 覆盖(删除数组元素)
  • 交换数组元素(用于排序等)

当然如果用容器的话,像删除和排序可以直接用一些方法来实现

二、二分查找

leetcode 704题

核心思想是不断与中间元素比较,确定是左边的区间还是右边的区间,需要注意的是这里用到的双指针是左闭右闭,即[left,right],搞清楚这一点就比较容易了。具体代码参考如下:

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

这里还需要理解的是循环结束后left和right的位置,若没有找到元素,left=right+1,从而跳出循环,返回-1。此时left左边的数表示的是比target要小的数(不包括left指向的数本身),而right右边表示比target大的数(不包括right指向的数)。有些题目会利用这一点出题,比如:

leetcode 35 搜索插入位置

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

要找的插入位置其实就是比target大的第一个元素的位置,也就是left。

下面再看一道题是利用两次二分查找确定相同元素的最大最小位置

leetcode 34题 

class Solution {
public:vector<int> searchRange(vector<int>& nums, int target) {int left = 0;int right = nums.size()-1;int first = -1;int last = -1;while(left<=right){int mid = (left+right) / 2;if(nums[mid] == target){first = mid;right = mid - 1; //从左边中继续找相等的元素,直到是最左边为止}else if(nums[mid] > target) right = mid - 1;else left = mid + 1;}left = 0;right = nums.size() - 1;while(left <= right){int mid = (left+mid) / 2;if(nums[mid] == target){last = mid;left = mid+1; //在mid右边继续找有没有相等的元素,直到最右边为止}else if(nums[mid] > target) right = mid - 1;else left = mid + 1;}return vector<int>{first,last};}
};

第一个注释确保了即使找到目标值,也会继续向左搜索,以确保找到第一个出现的索引。
第二个注释确保了即使找到目标值,也会继续向右搜索,以确保找到最后一个出现的索引。

三、移除元素

leetcode 27 移除元素

这道题的本质就是要删除掉指定的元素,一种方法是直接覆盖(暴力),参考代码如下:
 

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

另一种方法是快慢指针,可以直接在原数组上实现覆盖。其中,

快指针:用于遍历旧的数组,来找到符合条件的元素

慢指针:指向新数组下标

参考代码如下:

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

四、有序数组的平方

leetcode 977 有序数组的平方

这道题也是运用了双指针,因为新数组的最大值只可能出现在旧数组的首位,因此我们创建一个新数组,用k指向新数组最后,之后遍历旧数组,看看那边是最大值,就放入新数组中。参考代码如下:

class Solution {
public:vector<int> sortedSquares(vector<int>& nums) {int k = nums.size()-1; //用于指向新数组的指针vector<int> result(nums.size(),0);for(int i=0,j=nums.size()-1;i<=j;){if(nums[i]*nums[i] < nums[j]*nums[j]){result[k] = nums[j]*nums[j];j--;k--;}else{result[k] = nums[i]*nums[i];i++;k--;}}return result;}
};

总结一下今天刷的题目,通常数组在有时间复杂度要求或滑动窗口的情况下,要考虑用双指针。

http://www.dtcms.com/a/272379.html

相关文章:

  • 【高等数学】第三章 微分中值定理与导数的应用——第二节 洛必达法则
  • 关闭实时防护
  • Qt Creator控件及其用途详细总结
  • LeetCode经典题解:49、字母异位词分组
  • 游戏开发问题记录
  • 数字孪生技术为UI前端赋能:实现产品设计的快速原型验证
  • 小程序开发平台,自主开发小程序源码系统,多端适配,带完整的部署教程
  • Day57
  • 从零开始搭建深度学习大厦系列-2.卷积神经网络基础(5-9)
  • Redis性能基准测试
  • 影刀 RPA:实时追踪网页变化,第一时间推送通知
  • 知微传感Lkam系列线扫轮廓仪SDK例程篇:设置工作逻辑
  • Ubuntu 20.04 下**安装 FFmpeg 5.1
  • TCP 保活(KeepAlive)机制详解
  • 汽车功能安全-软件集成和验证(Software Integration Verification)【验证方法用例导出方法输出物】10
  • Java入门之JDK下载和安装
  • Thrust库介绍与使用
  • 《汇编语言:基于X86处理器》第7章 整数运算(1)
  • 机器人接入AI的发展前景:从开发者视角看技术融合与生态构建
  • JavaScript中的Screen对象:你的屏幕“身份证”
  • 城市规则管理列表实现逻辑
  • 【Note】Linux Kernel 实时技术深入:详解 PREEMPT_RT 与 Xenomai
  • 【React】MQTT + useEventBus 实现MQTT长连接以及消息分发
  • 昇腾 k8s vnpu配置
  • 在Linux中,如何使用grep awk sed find?
  • 链式二叉树数据结构(递归)
  • 自动化——bat——批量复制所选的文件
  • 微服务架构的演进:迈向云原生——Java技术栈的实践之路
  • SpringBoot整合腾讯云新一代行为验证码
  • RabbitMQ 幂等性