单链表、双链表结构
题目
笔试时尽量快,面试时时间复杂度和空间复杂度都要考虑
判断链表是否是回文(正、反遍历的结果一样)
- 出入栈:空间复杂度O(N)
(1)遍历链表并将元素放入栈
(2)遍历链表并与出栈的元素比较,若每个都相同则回文(因为出栈相当于逆序遍历链表) - 空间复杂度O(N/2),快慢指针:单链表长度未知,只能依次遍历。设置两个指针S和F,S一次走一步,F一次走两步,当F走到尾节点时,S在中间节点。
- 不同场景,不同边界条件,如F结束时,S具体应停在中间节点or中间节点的前一个等,需要写熟。
(1)从链表的中间节点遍历,将元素入栈
(2)从链表的头节点遍历,并与出栈元素比较,若每个都一样,则回文
- 不同场景,不同边界条件,如F结束时,S具体应停在中间节点or中间节点的前一个等,需要写熟。
- 空间复杂度O(1)
快慢指针找到中间节点,将后半部分反向,用两个指针分别从两端遍历,若每一个元素都相同则回文,最后要将链表后半部分的指向恢复。
将单向链表按某值划分为左边小、中间相等、右边大的形式
- 笔试:放入数组中,在分左中右
- 面试:六个节点,分别指向左中右的头尾,遍历链表,最后将三个大中小链表的头尾相接为一个链表。要考虑没有小、等、大节点的情况。
复制含有随机指针节点的链表
- 笔试:额外空间O(N)
(1)用哈希表存储链表所有节点,key和value一样
(2)遍历链表,将每个节点的next、rand存入哈希表 - 面试:额外空间O(1)
(1)克隆原节点到原节点的next,原节点的rand不变,形成新的链表
(2)遍历新链表,将克隆节点的rand改为原节点rand的克隆节点(即原节点rand的下一个)
环形链表第一个入环节点
快慢指针f, s,f走两步,s走一步,f和s会在环内相遇,即指向同一个节点(因为f的速度时s的两倍,所有在环内s绕环不会超过两圈,一定会和f相遇),相遇后s不动,将f指向头节点,然后f、s每次都走一步,当f走到第一个入环节点时,s也到了该节点,f, s相遇,记相遇节点为loop.
相交链表
- 两个无环链表的相交:leetcode160
- 环形链表相交
- 一个无环链表和一个有环链表不会相交
- 两个有环链表但,loop1 和looop2不相等:loop2不动,loop1继续遍历,若loop1在转回loop1之前没有遇到loop2,则两个有环链表不相交 ,返回相交节点null;若loop1和loop2相遇则相交,返回第一个相交节点loop1, loop2都行。
- 两个有环链表相交,且loop1 = loop2:将loop1认为是两个链表的尾节点,然后按照leetcode160的方式,找到两个链表的第一个相交节点。