当前位置: 首页 > 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.lryc.cn/news/584748.html

相关文章:

  • 如何安装python以及jupyter notebook
  • 黄瓜苦多于意外,苦瓜苦来自本源——“瓜苦”探源
  • BERT模型基本原理及实现示例
  • 强化学习 MDP
  • 从代码生成到智能运维的革命性变革
  • 集成平台业务编排设计器
  • 在虚拟机中安装Linux系统
  • 下一代防火墙-终端安全防护
  • 【数据结构】顺序表(sequential list)
  • Python3邮件发送全指南:文本、HTML与附件
  • 力扣61.旋转链表
  • 【会员专享数据】2013-2024年我国省市县三级逐日SO₂数值数据(Shp/Excel格式)
  • 【Linux基础命令使用】VIM编辑器的使用
  • WinUI3入门17:本地文件存储LocalApplicationData在哪里
  • 企业数据开发治理平台选型:13款系统优劣对比
  • Building Bridges(搭建桥梁)
  • HVV注意事项(个人总结 非技术)
  • 在VMware中安装虚拟机
  • 数据结构 --- 队列
  • XCZU47DR-2FFVG1517I Xilinx FPGA AMD ZynqUltraScale+ RFSoC
  • 超声波刻刀适用于一些对切割精度要求高、材料厚度较薄或质地较软的场景,典型应用场景如下:
  • 测试开发和后端开发到底怎么选?
  • UGF开发记录_3_使用Python一键转换Excle表格为Txt文本
  • 穿梭时空的智慧向导:Deepoc具身智能如何赋予导览机器人“人情味”
  • Qt中处理多个同类型对象共享槽函数应用
  • 广州华锐互动在各领域打造的 VR 成功案例展示​
  • pycharm无法识别pip安装的包
  • 【佳易王中药材划价软件】:让中药在线管理高效化、复制文本即可识别金额自动计算#中药房管理工具#快速划价系统#库存与账单一体化解决方案,软件程序操作教程详解
  • 多线程 JAVA
  • MySQL索引操作全指南:创建、查看、优化