第一天——数组

二分查找

首先需要注意的是,二分查找需要随机寻址和关键字有序,不然不可使用。

关于二分法,最重要的要点在于区间定义和二分中点的更新,现总结如下:

左右为闭区间的二分查找

循环条件:左浮标小于等于右浮标

左右区间更新:中间位置 + / - 1

代码示例:

class Solution {public:int search(vector<int>& nums, int target) {int left = 0;int right = nums.size() - 1; // 定义target在左闭右闭的区间里,[left, right]while (left <= right) { // 当left==right,区间[left, right]依然有效,所以用 <=int middle = left + ((right - left) / 2);// 防止溢出 等同于(left + right)/2if (nums[middle] > target) {right = middle - 1; // target 在左区间,所以[left, middle - 1]} else if (nums[middle] < target) {left = middle + 1; // target 在右区间,所以[middle + 1, right]} else { // nums[middle] == targetreturn middle; // 数组中找到目标值,直接返回下标}}// 未找到目标值return -1;}
};

左闭右开的区间的二分查找

循环条件:左浮标小于右浮标

左右区间更新:左浮标更新为中间位置+1、右浮标更新为中间位置

代码示例:

class Solution {public:int search(vector<int>& nums, int target) {int left = 0;int right = nums.size(); // 定义target在左闭右开的区间里,即:[left, right)while (left < right) { // 因为left == right的时候,在[left, right)是无效的空间,所以使用 <int middle = left + ((right - left) >> 1);if (nums[middle] > target) {right = middle; // target 在左区间,在[left, middle)中} else if (nums[middle] < target) {left = middle + 1; // target 在右区间,在[middle + 1, right)中} else { // nums[middle] == targetreturn middle; // 数组中找到目标值,直接返回下标}}// 未找到目标值return -1;}
};

数组元素删除

力扣原题

由于数组的地址是连续的,因此要删除某一个元素,不可以直接将其删除,而是需要调整后续的元素位置来填补删除元素后留下的位置空缺(这里需要与链表区分开来)

如果采用每次扫过整个数组,每次删除一个元素,我们得到的算法解决效率较低

  • 时间复杂度:
    O(n2)O(n^2) O(n2)

  • 空间复杂度:
    O(1)O(1) O(1)

比较高效的方法是采用双指针,两个指针同时往下扫描整个数组,快指针提取记录,慢指针写入记录,如果遇到要移除的记录就将快指针后跳以覆盖记录。

代码如下:

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;}
};
  • 时间复杂度:

O(n)O(n) O(n)

长度最小的子数组

力扣原题

这算是一道经典的滑动窗口题了,由于数组内均为正整数,我们只需要从数组开始位置设置一个起点和终点,当起点终点内的数字之和小于目标,向右扩展终点,否则从左缩小起点。这样一次遍历数组即可得到结果。

代码如下:

class Solution {public:int minSubArrayLen(int s, vector<int>& nums) {int result = INT32_MAX;int sum = 0; // 滑动窗口数值之和int i = 0; // 滑动窗口起始位置int subLength = 0; // 滑动窗口的长度for (int j = 0; j < nums.size(); j++) {sum += nums[j];// 注意这里使用while,每次更新 i(起始位置),并不断比较子序列是否符合条件while (sum >= s) {subLength = (j - i + 1); // 取子序列的长度result = result < subLength ? result : subLength;sum -= nums[i++]; // 这里体现出滑动窗口的精髓之处,不断变更i(子序列的起始位置)}}// 如果result没有被赋值的话,就返回0,说明没有符合条件的子序列return result == INT32_MAX ? 0 : result;}
};

螺旋数组

力扣原题

这种题就挺搞人的,基本就是看你能不能搞明白边界条件。

为了统一循环条件,我们统一每条边的填充都是左闭右开。如题目的3阶矩阵,我们就先填充1,2、再填充3,4、再填充5,6、再填充7,8,最后补充9即可。因为统一了循环条件,每次填充的值的数量是固定的,最后要不要填充一个中间数则由起始的条件决定。这样我们就完成了边界条件的判断。

代码如下:

class Solution {public:vector<vector<int>> generateMatrix(int n) {vector<vector<int>> res(n, vector<int>(n, 0));int psx = 0, psy = 0; // 定义起始位置int loop = n / 2; // 循环的圈数int mid = n / 2; // 螺旋数组的中间位置int count = 1; // 赋值初始化int offset = 1; // 数组循环时的边长控制int i, j;while (loop --){i = psx;j = psy;// 填充外圈for (j = psy; j < psy + n - offset; j++){res[psx][j] = count++;}for (i = psx; i < psx + n - offset; i++){res[i][j] = count++;}for (; j > psy; j--){res[i][j] = count++;}for (; i > psx; i--){res[i][j] = count++;}// 下一圈开始时调整起始位置和偏移量offset += 2;psx++;psy++;}// 如果n为奇数在中间填充最后一个数if (n % 2){res[mid][mid] = count;}return res;}
};

数据结构第一天之数组相关推荐

  1. 【Java数据结构与算法】第一章 稀疏数组和队列

    第一章 稀疏数组和队列 文章目录 第一章 稀疏数组和队列 一.线性结构和非线性结构 1.线性结构 2.非线性结构 二.稀疏数组 三.队列 1.队列 2.环形队列 一.线性结构和非线性结构 1.线性结构 ...

  2. 数据结构与算法---稀疏数组

    数据结构与算法-稀疏数组 1.基本介绍: ​ 当一个数组中大部分元素为0,或者为同一个值的数组时,可以使用稀疏数组来保存该数组. 2.稀疏数组的处理方法是: ​ (1)记录数组一共有几行几列,有多少个 ...

  3. 看得见的数据结构Android版之数组表(数据结构篇)

    零.前言: 一讲到装东西的容器,你可能习惯于使用ArrayList和数组,你有想过ArrayList和数组的区别吗? Java的类起名字都不是随便乱起的,一般前面是辅助,后面是实质:ArrayList ...

  4. python求数组最大值_Python算法与数据结构--求所有子数组的和的最大值

    Python算法与数据结构--求所有子数组的和的最大值 玄魂工作室秘书 玄魂工作室 昨天 题目:输入一个整形数组,数组里有正数也有负数.数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和. ...

  5. JavaScript数据结构和算法简述——数组

    为什么先讲数组 数据结构可以简单的被分为线性结构和非线性结构. 线性结构大致包括: 数组(连续存储): 链表(离散存储): 栈(线性结构常见应用,由链表或数组增删和改进功能实现): 队列(线性结构常见 ...

  6. 数据结构:串、数组和广义表

    串 线性结构:线性表.栈和队列.串与数组和广义表 串的逻辑结构和线性表极为相似,区别仅在于串的数据对象限定为字符集.在基本操作上,串和线性表有很大差别.线性表的基本操作主要以单个元素作为操作对象,如查 ...

  7. Java数据结构第一讲-排序算法

    常见数据结构和算法实现(排序/查找/数组/链表/栈/队列/树/递归/海量数据处理/图/位图/Java版数据结构) 数据结构和算法作为程序员的基本功,一定得稳扎稳打的学习,我们常见的框架底层就是各类数据 ...

  8. 大话西游之王道考研数据结构第一讲---线性表的顺序表示

    大话西游之王道考研数据结构第一讲---线性表的顺序表示 写在前面的话 王道考研数据结构是一本非常好的书,本系列所有的内容是按照其书进行讲述的,所以您可以以那本书作为主要内容,这个做参考. 大学时候,在 ...

  9. [数据结构与算法] 串,数组和广义表

    串偏向于算法,数组和广义表偏向于理解 第四章 串.数组和广义表 4.1 串的定义 4.2 案例引入 4.3 串的类型定义,存储结构及运算 4.3.1 **串的类型定义** 4.3.2 串的存储结构 4 ...

最新文章

  1. 萨默尔机器人_沣东新城王寺街道《民法典》企业宣传活动走进西安萨默尔科技...
  2. sublime搭建C/C++编译环境(超完美的配置并配上内容详细讲解!!)
  3. 深入理解JS中this关键字
  4. simditor存储数据到前台展示去掉标签
  5. boost::gregorian模块实现自出生以来的天数的测试程序
  6. c语言交换两个数字 位运算_交换两个8位数字| 8086微处理器
  7. java version 和javac版本不一致_windows安裝多個版本的jdk,解決java-version和javac-version版本不一致的問題...
  8. 全球首发!计算机视觉Polygon Mesh Processing读书笔记6——微分几何中的Metric Properties
  9. L1-080 乘法口诀数列 (20 分)-PAT 团体程序设计天梯赛 GPLT
  10. 顶部吸附_吸附脱附催化燃烧的工作原理
  11. 本人教你五分钟学会五笔(不服找我)
  12. java word_java输出word解决方案
  13. 多态与虚函数(C++)
  14. 2018初中计算机考试知识点,[2018年最新整理]全国计算机一级考试MS_Office知识点.docx...
  15. window 获取cpu型号_教你如何修改电脑上的CPU型号信息!
  16. python f检验 模型拟合度_Python 爬取北京二手房数据,分析北漂族买得起房吗? | 附完整源码...
  17. LICEcap 一款小巧的GIF屏幕录制软件
  18. java计算机二级知识点、易错点整理(三)
  19. 无法执行磁盘检查,因为windows无法访问该磁盘的一种解决思路
  20. 情人节用Python画玫瑰花

热门文章

  1. GStreamer功能详解
  2. w ndows11如何设置电源选项,苹果安卓都支持 惠普1200W使用指南
  3. MySQL慢查询语句
  4. fragment 切换判断界面是否可见 setUserVisibleHint和onHiddenChanged使用场景
  5. 激活函数(5)ELU函数、PReLU函数
  6. 请用c++写一个视频为转换成GIF的代码
  7. 语音视频聊天时会产生爆音
  8. JavaScript基础--改变this指向的方法
  9. 【计量模型整理】偏最小二乘回归 PLS
  10. OPENFLOW协议协议分析实践