扩展题目
- 24解法1:
cpp
// 迭代法难搞
ListNode* swapPairs(ListNode* head) {
if(head == nullptr || head->next == nullptr) return head;
ListNode* ret = head->next;//用于返回的节点
ListNode* p1 = head;
ListNode* p2 = p1->next;
ListNode* p3 = p2->next;//首先记录三个节点
ListNode* tail = new ListNode();//记录本次操作的尾结点
while(p3)
{
p2->next = p1;//p2指向p1
p1->next = p3;//p1指向下一次要翻转的p3,保证链表不断
tail->next = p2;//上次的尾节点指向本次的头
if(p3->next == nullptr) break;//如果此时p3->next为空,说明到链表尾部了,结束
tail = p1;//更新tail,p1, p2, p3
p1 = tail->next;
p2 = p1->next;
p3 = p2->next;
}
tail->next = p2;//结束循环后,tail指向当前的p2
p2->next = p1;//p2指向p1
p1->next = p3;//p1指向p3
return ret;
}
- 24解法2
cpp
//递归np
ListNode* swapPairs(ListNode* head) {
if(head == nullptr || head->next == nullptr)
return head;
ListNode* p1 = head;
ListNode* p2 = head->next;
p1->next = swapPairs(p2->next);
p2->next = p1;
return p2;
}
- 25解法1
cpp
// 迭代解法
ListNode* reverse(ListNode* head)
{
if(head == nullptr || head->next == nullptr) return head;
ListNode* node1 = head;
ListNode* node2 = node1->next;
while(node1 && node2 && node2->next)
{
node1 = node2;
node2 = node2->next;
}
node1->next = nullptr;//node1为倒数第二个节点,node2为尾结点
node2->next = reverse(head);//断开node1,node2指向翻转号的剩余head
return node2;
}
ListNode* reverseKGroup(ListNode* head, int k) {
if(head == nullptr || head->next == nullptr) return head;
ListNode* tail = head;//记录当前中移动节点,可以放在while中
ListNode* nextHead = head;//记录下一次翻转的头节点
ListNode* res = nullptr;//用于返回
ListNode* lastTail = nullptr;//记录上一次翻转的尾结点
while(nextHead)
{
ListNode* curHead = nextHead;//此次的头结点
tail = nextHead;//滑动节点
int i = k;//单独一个变量记录i
while(--i && tail) tail = tail->next;//找到本次翻转的尾结点,或者链表尾
if(tail == nullptr)//如果已经到链表尾结点,不用再翻转
{
lastTail->next = nextHead;//上次的尾结点指向当前的尾,然后结束
break;
}
nextHead = tail->next;//首先更新下一个Head
tail->next = nullptr;//当前tail断开
ListNode* ret = reverse(curHead);//把本次处理的链表翻转
if(res == nullptr) res = ret;//用于返回res等于第一次翻转的链表
if(lastTail)//使用每一个node的时,都要显式的判断一下是否为空
lastTail->next = ret;//上次的tail指向本次翻转链表的头
ListNode* curTail = ret;//求取本次翻转链表之后的tail
while(curTail && curTail->next) curTail = curTail->next;
lastTail = curTail;//更新此次tail
}
return res;
}
- 25解法2
cpp
ListNode* reverse(ListNode* node1, ListNode* node2)
{
ListNode* pre = nullptr;
ListNode* cur = node1;
ListNode* next = nullptr;
while(cur != node2)
{
next = cur->next;
cur->next = pre;
pre = cur;
cur = next;
}
return pre;
}
ListNode* reverseKGroup(ListNode* head, int k) {
if(head == nullptr || head ->next == nullptr) return head;
ListNode* node1 = head;
ListNode* node2 = head;
int i = k;
while(i-- && node2) node2 = node2->next;//找到翻转链表的下一个结点
if(node2 == nullptr && i >= 0)//如果到达链表尾部,直接返回
return node1;
ListNode* newHead = reverse(node1, node2);//翻转链表
node1->next = reverseKGroup(node2, k);//递归进入下一轮
return newHead;
}