list
基础知识
回文操作
快慢指针具体的使用需要看具体的情况。比如在**包含头节点的链表**中,将慢指针初始化为首元素节点,快指针初始化为头节点,那么:
- 链表长度为奇数:循环终止时,慢指针恰好位于中点位置
- 链表长度为偶数:循环终止时,慢指针位于链表的右中位置
在不包含头节点的链表中,快慢指针都初始化为首元素节点,那么:
- 链表长度为奇数:循环终止时,慢指针恰好位于中点
- 链表长度为偶数:循环终止时,慢指针位于上中位置。
我个人人为带有头节点的链接更好用,因为在使用反转链表原地判断是否为回文时,更加方便,当链表长度为偶数时,慢指针位于右半序列的第一个元素,更方便反转。
链表的基本操作
反转链表
面试做法:时间复杂度O(N)
将后半部分数据反转,即反转单链表,中点位置数据的next指向null,然后头和尾依次比较,比较完成后,还需要将链表调回正常状态
算时间用纳秒
## 链表实现荷兰国旗问题
**笔试做法**:先将数据放入数组中,在数组中完成荷兰国旗,然后再将数据中的数据重新串成链表,实现非常简单,再次不过多赘述。
---
**面试做法**:保证稳定性,且额外i空间为常数
小于区域、等于区域、大于区域都有头和尾两个变量表示,初始时都为null
``` c++
void PartitionLinkNoSpace(node* head, int pivot)
{
if (!head->next)
return;
node* les_beg{ nullptr }, * les_end{ nullptr },
* equ_beg{ nullptr }, * equ_end{ nullptr },
* gtr_beg{ nullptr }, * gtc++r_end{ nullptr };
node* cur = head->next;
node* next{ nullptr };
while (cur)
{
+ next = cur->next;
+ cur->next = nullptr;
if (cur->value < pivot)
{
if (les_beg && les_end)
{
//end后面的空指针丢就丢了,因为新插入的节点自带null指针
les_end->next = cur;
les_end = cur;
}
else
{
les_beg = les_end = cur;
}
}
if (cur->value == pivot)
{
if (equ_beg && equ_end)
{
equ_end->next = cur;
}
else
{
equ_beg = equ_end = cur;
}
}
if (cur->value > pivot)
{
if (gtr_beg && gtr_end)
{
gtr_end->next = cur;
gtr_end = cur;
}
else
{
gtr_beg = gtr_end = cur;
}
}
- cur=cur->next;
+ cur = next;
}
// link the less equal greater area
//如果小于区域存在,则小于区域尾节点连接equ_beg
if (les_beg)
{
les_end->next = equ_beg;
//等于区域存在,则equ_end是等于区域尾节点
//等于区域不存在,equ_end是小于区域尾节点
//哪个区域存在,哪个去连接大于区域
equ_end = equ_end ? equ_end:les_end ;
}
if (equ_end)
{
equ_end->next = gtr_beg;
}
les_beg = les_beg ? les_beg : (equ_beg ? equ_beg : gtr_beg);
head->next = les_beg;
return;
}复制含有随机指针的链表
判断两个链表(可能有环)的第一个公共节点
判断链表是否有环
判断首个相交节点
其他
cpp的map结构
cpp的stack结构
Last updated