目录
5. 给定一个链表,返回链表开始入环的第一个结点。 如果链表无环,则返回 NULL
6. 给定一个链表,每个结点包含一个额外增加的随机指针,该指针可以指向链表中的任何结点或空结点。
1.链表分割
题目:
现有一链表的头指针 ListNode* pHead,给一定值x,编写一段代码将所有小于x的结点排在其余结点之前,且不能改变原来的数据顺序,返回重新排列后的链表的头指针。
相对顺序不能变
5 3 2 8 1 6 x=4
3 2 1 5 8 6
思路:
1.定义两个链表:
less
greater
lesshead和greaterhead是哨兵位的头结点
2.
比x小的尾插到less链表
比x大的尾插到great链表
3.
两个链接到一起,lesstail->next指向greaterhead->next
最后将两个lesshead和greaterhead释放掉
建议定义哨兵位,比较简单
分析极端场景
- 都比x小
- 都比x大
- 有大有小
注意:
第三种场景中可能会出现代还
代还,此时8还是指向1
解决方法:
greatertail->next = NULL;
此方法是带哨兵位的头结点
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};*/
class Partition {
public:
ListNode* partition(ListNode* pHead, int x) {
// write code here
struct ListNode* greaterhead, *greatertail,*lesshead,*lesstail;//一次性定义四个指针
greaterhead = greatertail = (struct ListNode*)malloc(sizeof(struct ListNode));
lesshead = lesstail = (struct ListNode*)malloc(sizeof(struct ListNode));
greatertail->next = NULL;
lesstail->next = NULL;
struct ListNode* cur = pHead;//pHead是现有链表的头指针
while(cur)
{
//链表中小于x的数将被尾插进less链表中
if(cur->val < x)
{
lesstail->next = cur;//尾插进去
lesstail = lesstail->next;//更新lesstail
}
//比x大的数被尾插进great链表中
else
{
greatertail->next = cur;
greatertail = greatertail->next;
}
cur = cur->next;//更新cur
}
//链接两个链表
lesstail->next = greaterhead->next;
//解决代还现象
greatertail->next = NULL;
struct ListNode* head = lesshead->next;//定义头指针
//将两个哨兵位释放掉
free(greaterhead);
free(lesshead);
return head;//返回重新排列后的链表的头指针
}
};
注意:
这道题在vs中想要调试的时候可能与其他题目调试有所不一样,因为代码中含有C++的代码,与C语言的语法有所差异,调试的时候就有可能编译不过去。
方法:
把struct加上,把它当成C语言的函数进行调试,可以把C++的部分去掉
2.链表的回文结构
题目:
1 2 2 1
1 2 3 2 1
就是看链表是否对称
思路:
之前写过数组判断回文的方法:
给定两个指针(下标也可),一个在左一个在右,往中间走。
但是单链表并不支持如此写法。