目录
链表成环与成环位置检测
思路:利用快慢指针判断是否最终相遇
class Solution {
public:
bool hasCycle(ListNode *head) {
if(head==NULL || head->next==NULL ||head->next->next==NULL) return false;
auto p1=head;
auto p2=head;
while(p1!=NULL && p2!=NULL &&p2->next!=NULL){
p1=p1->next;
p2=p2->next->next;
if(p1==p2) return true;
}
return false;
}
};
链表成环位置
思路:从表头到成环位置长度 == 从环中相遇位置到成环位置
因此,只要在快慢指针相遇后,分别从相遇处,以及表头开始前进,二者再次相遇处即为成环位置
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
if(head==NULL || head->next==NULL || head->next->next==NULL) return NULL;
//注意此处将快慢指针都初始化在起始位置,从而保证二者后面走过的路程为2倍关系
auto pF=head;
auto pS=head;
while( pF->next && pF->next->next){
pF=pF->next->next;
pS=pS->next;
if(pF==pS){
break;
}
}
if(pF==NULL || pS==NULL || pS!=pF) return NULL;
pF=head;
while(pF != pS){
pF=pF->next;
pS=pS->next;
}
return pF;
}
};
反转链表!!!
翻转链表有递归与非递归两种解法。
递归解法本质类似于二叉树的后序遍历,先遍历当前节点的后面节点,同时保存上一次访问的节点,从而将上一次访问的节点即当前节点的后继节点连接到当前。
非递归解法
ListNode*reverse2(ListNode*head){
if(head==NULL || head->next==NULL) return head;
//注意许多链表问题中,表头经常要特殊处理,为了避免对表头的特殊处理,
//经常可以造一个临时表头
ListNode fake(-1);
auto p=head;
while(p){
if(fake.next==NULL){
fake.next=p;
p=p->next;
fake.next->next=NULL;
}
else{
auto next=p->next;
p->next = fake.next;
fake.next=p;
p=next;
}
}
return fake.next;
}
递归解法
ListNode*lastVisited;//保存后序遍历中上一次访问节点
ListNode*reverseHead;//保存翻转的表头
void reverseList(ListNode*node){
if(node->next==NULL){
reverseHead=node;
lastVisited=node;
}else{
//后序遍历,先访问后继节点
reverseList(node->next);
lastVisited->next=node;
node->next=NULL;
lastVisited=node;
}
}
按K组翻转链表!!!
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
ListNode*lastVisited;
ListNode*reverseHead;
void reverseList(ListNode*node){
if(node->next==NULL){
reverseHead=node;
lastVisited=node;
}else{
reverseList(node->next);
lastVisited->next=node;
node->next=NULL;
lastVisited=node;
}
}
//非递归的翻转除表头外链表的剩余部分
void reverseList1(ListNode*pHead){
if(pHead->next==NULL || pHead->next->next==NULL) return;
auto p1=pHead->next;
while(p1->next){
auto p2=p1->