原本计划上周末完成的算法数组篇,由于打球崴了脚,持续的疼痛无法静下心来码字,然后就
了
贴了两天狗皮膏药,肿居然消了,那就开撸吧,今晚必须发稿
先来看看书上的解释:数组是有序的元素序列。若将有限个类型相同的变量的集合命名,那么这个名称为数组名。组成数组的各个变量称为数组的分量,也称为数组的元素,有时也称为下标变量。用于区分数组的各个元素的数字编号称为下标。数组是在程序设计中,为了处理方便, 把具有相同类型的若干元素按有序的形式组织起来的一种形式。这些有序排列的同类数据元素的集合称为数组.
从这段描述中我们很容易提取出数组的四个特性
1.元素有序
2.数量有限
3.类型相同
4.有下标
实际上除了这四点外在还要补充一个特性:内存上连续
通过利用这些特性,我们就有了很大的操作空间,首先元素类型相同,有序,内存连续,那么只要知道一个元素的位置,我们就可以依次找到他的下一个元素,下下个元素...这样好像很麻烦,没事,我们还有下标,通过下标计算内存偏移,就可以直接找到对应的元素,这效率,杠杠的.切记:元素数量有限,因此数组有边界,严禁越界,否则,将遭受致命打击特性说的差不多了,在来看看实际上的应用,我的理解是可以分为三类,单指针,双指针,多指针.(文中算法题来自LeetCode,解题代码来自作者本人)
一.单指针
单指针就是利用一个额外的指针对数组进行标记,通过不断的处理该指针指向的值和改变该指针的指向达到目的,比如查询记录某个元素,删除某个元素,在特定元素前后插入新的元素,修改特定元素的值.(补充:遍历删除元素时一般从后往前遍历)
例题: 给定一个有序数组nums,请原地删除重复出现的元素,使得出现次数超过两次的元素只出现两次 ,返回删除后数组的新长度。不要使用额外的数组空间,必须在原地修改输入数组并在使用O(1) 额外空间的条件下完成
解: 数组有序,可以从后往前进行遍历,通过额外的指针记录第一次重复出现的元素,当第二次重复出现时进行删除即可
二.双指针 相比单指针,顾名思义就是两个额外的指针啦,虽然只是多了一个指针,但是可操作性远远比单指针要丰富很多(可以想象两只手与一只手🙃),比如,两个指针一个从前往后走,一个从后往前走,就形成了对撞指针,也可以一个走得慢,一个走得快,形成快慢指针,还可以你追我赶,完成滑动窗口.灵活运用,乐趣无穷
例题: 给定一个含有n个正整数的数组和一个正整数target。找出该数组中满足其和≥target的长度最小的连续子数组[numsl, numsl+1, ..., numsr-1, numsr],并返回其长度。如果不存在符合条件的子数组,返回0
解: 可以通过滑动窗口,前指针移动不断扩大数组直到满足和大于target,然后后指针前移动寻找最小的区间,直达不满足和大于target,重新移动前指针,循环移动直到窗口到达尾部
例题: 给定一个字符串 s ,仅反转字符串中的所有元音字母,并返回结果字符串。元音字母包括 'a'、'e'、'i'、'o'、'u',且可能以大小写两种形式出现。
解: 这是一个典型的前后数据交换问题,可以通过对撞指针解决,头尾两个分别向对方移动,当一个指针满足条件时等待另一个指针,两个指针都满足时进行数据交换,然后继续移动,循环直到两个指针相遇.
三.多指针 多指针使用相对较少,因其可读性,复杂度相对较高,大多数问题会使用双指针结合分治,递归等方式处理.当然,对于某些特定问题,比如数据分区分类,区域数据交换...多指针也是一个很好的解决方案
例题: 给定一个包含红色、白色和蓝色、共n个元素的数组nums,原地对它们进行分类排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。使用整数0、1和2分别表示红色、白色和蓝色。
解: 可以使用两个指针分别位于数组头部和尾部,第三个指针对数组进行遍历,将0数据与2数据分别传递给头尾指针.头部指针向尾部移动接收0数据,尾部指针向头部移动接收2数据.
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。