算法刷题(一)-数组篇

一、预备知识

  1. 概念

数组是存放在连续内存空间上的相同类型数据的集合。

  1. 特性
  • 数组下标都是从0开始的;

  • 数组内存空间的地址是连续的;

  • 数组的元素不能删除,只能覆盖;

因为数组的在内存空间的地址是连续的,所以我们在删除或者增添元素的时候,就难免要移动其他元素的地址。

如果使用C++的话,要注意vector 和 array的区别,vector的底层实现是array,严格来讲vector是容器,不是数组。

注意:C++中二维数组是连续分布的,而Java中是不连续分布的。

二、二分查找

  1. 题目描述
  1. 题解
1)法一:(时:o(logn),空:o(1))

注意循环不变量原则:在while寻找中每一次边界的处理都要坚持根据区间的定义来操作。

  1. 注意的知识点

1)left + (right - left) / 2防溢出;

2)vector容器:只有C++11以上才可利用列表初始化;.size()可以获取容器大小;

三、移除元素

  1. 题目描述
  1. 题解
1)法一:暴力解法(时:o(n^2),空:o(1))

双层for循环,一个for循环遍历查找要删除的数组元素 ,第二个for循环更新数组。

2)法二:双指针法(时:o(n),空:o(1))

快指针用于查找新的数组元素(即无需删除的元素),慢指针指向要删除的数组元素。

  1. 注意的知识点

1)数组的元素在内存地址中是连续的,不能单独删除数组中的某个元素,只能覆盖;

四、有序数组的平方

  1. 题目描述
  1. 题解
1)法一:暴力解法(时:O(n+nlogn),空:O(1))

每个元素平方后进行排序。

2)法二:双指针法(时:O(n),空:o(1))

数组本来有序, 只不过负数平方之后可能影响次序,故数组平方的最大值就在数组的两端,不是最左边就是最右边。

  1. 注意的知识点

1)vector向量,可理解为“变长数组”(即“长度根据需要而自动改变的数组);

2)iterator迭代器,可理解为一种类似指针的东西,可以通过 *it 来访问vector里的元素;

3).begin()函数: 取首元素地址;.end()函数:取尾元素地址的下一个地址,作为迭代器末尾标志,不存储任何元素;

4)vector<int> a(n, 0)创建大小为n且元素初始值为0的容器;

五、长度最小的子数组

  1. 题目描述
  1. 题解
1)法一:暴力解法(时:O(n^2),空:o(1))

两层for循环依次遍历寻找合适的子序列。

2)法二:滑动窗口(时:o(n),空:o(1))

根据当前子序列和大小的情况,不断调节子序列的起始位置。当前窗口的值>=target时,窗口就要向前移动(即向后调整窗口的起始位置);窗口的结束位置为遍历数组的指针,也就是for循环里的索引。

注:时间复杂度看每一个元素被操作的次数。每个元素在滑动窗后进来操作一次,出去操作一次,每个元素都是被操作两次,所以时间复杂度是 2 × n 也就是O(n)。

3)法三:前缀和+二分法(时:o(nlogn),空:o(1))

新建一个数组sums用于存储前i个元素的和,可以将寻找target的子序列转换为寻找和为sums[i]-target的前缀和,利用二分法在sums中寻找满足<=该前缀和的下标(即子序列起始位置的前一位)。

  1. 注意的知识点

1)INT32_MAX可表示初试最大值;

2)滑动窗口思想:根据当前子序列和大小的情况,不断调节子序列的起始位置;

3)求解连续子数组的常用思路:滑动窗口;前缀和;

六、螺旋矩阵II

  1. 题目描述
  1. 题解
1)法一:模拟法(时:o(n^2),空:o(1))

模拟矩阵的生成。

  1. 注意的知识点

1)二维数组容器的定义:vector<vector<int>> mat;

2)二维数组迭代器的遍历;

七、总结

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值