剑指Offer-2.3节-数据结构
该节主要讲述了面试当中极易考察的几种数据结构。主要包括:数组、字符串、链表、树、栈和队列。
本章节涉及到了很多后续出现的题目,因此适合在读完全书后,再次阅读。
1. 数组中重复的数字
数组,占据一块连续的内存空间,并按照顺序存储数据。
因此可以根据下标在O(1)时间读/写任何元素。
在使用时,格外注意数组越界问题。
T3找出数组中重复的数字
剑指P39
3种方法,最优算法:时间复杂度,空间复杂度o(n)
方法 | 时间复杂度 | 空间复杂度 |
---|---|---|
对数组排序 | nlogn | |
哈希表 | n | n |
按下标对数组重排 | n | 1 |
不修改数组:二分法依次统计数字出现次数 | nlogn | 1 |
T4 二维数组中的查找
二维数组:自上至下递增,自左至右递增,在其中查找某数字。
对于解决复杂的问题,可以从一个具体例子入手,通过分析简单具体的例子,试图寻找普遍规律。
从右上角开始查找,如果待查找的数字小于右上角,则剔除当前列。如果带查找的数字大于右上角的数字,则剔除当前行。
以此不断缩小查找范围。
2. 字符串
对String的操作一般会生成一个新的实例,并在返回值中返回。
因此,每对String进行一次修改都会产生一个临时对象。开销太大会影响效率。
因此一般使用STringBuilder来连续多次修改字符串。
对于Java中的参数传值问题:https://blog.csdn.net/xiaohaigary/article/details/113396491
T5替换字符串中的空格为%20
首先要考虑清楚,是否在原来的字符串上进行操作?若是,是否有足够的字符串空间存储。
要求:在原字符串上进行操作,且有充足的空间。
从前向后进行替换的话,会导致后面部分的字符被多次移动。O(nn)
因此考虑,从后向前。
首先遍历一次,统计空格个数,乘2即时需要的扩充空间。
然后从后先前依次移动即可。 O(n)
合并两个数组、字符串,一般可以采用从后向前的方式。
3. 链表
T6从尾到头打印链表:
自然想法:
反转链表,然后顺序遍历即可。NC78
但该做法会修改链表结构。一般而言,打印即为访问。需要问清楚面试官是否可以修改。
初级想法:
遍历链表,挨个入栈,然后挨个出栈即可。
鲁棒性强。
延伸想法:
栈是递归的实现。递归的本质就是栈。
因此可以有递归的思路:
每访问到一个节点时,先递归输出它后面的节点,再输出该节点本身。
缺点:当链表非常长时,可能会导致函数调用栈溢出。
4. 树
需要对树的3中遍历的6种方法了如指掌。
二叉搜索树,堆,红黑树等。
T7根据前序、中序重建二叉树
采用递归的方法,不断针对划分左右子树,分别重建。
需要注意数组范围。
T8二叉树的下一节点
对中序遍历熟悉,分清楚每种情况,分类讨论即可。
5.栈和队列
操作受限的数据结构。
T9用两个栈实现队列
与用两个队列实现一个栈,极其相似。
相似之处:
入队操作全入一个栈。
入栈操作全入一个队中。
不同之处:
出队时,将A栈中的元素全部倒入B栈。然后出栈即出队。
出栈时,将A队列元素依次移入到B队列当中,A队列中的最后一个元素丢弃,即出栈。