Swap Nodes in Pairs
原题链接 Swap Nodes in Pairs
意思是将链表每两个节点互换位置,要求不能直接改变链表的值,只能改变next指针的方式交换
其实就是遍历一遍每两个交换即可,方法比较随意
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
if(!head)
return head;
/* 增加一个前驱节点,解决头部节点改变的问题 */
ListNode* header = new ListNode(-1);
header->next = head;
/* 每次都移动两步,直接交换,如果不足两步,就退出 */
ListNode* cur = head->next;
ListNode* prv = head;
ListNode* prv_last = header;
while(cur)
{
ListNode* next = cur->next;
prv_last->next = cur;
cur->next = prv;
prv->next = next;
if(next && next->next)
{
prv_last = prv;
prv = next;
cur = next->next;
}
else
{
break;
}
}
ListNode* res = header->next;
delete header;
return res;
}
};
Reverse Nodes in k-Group
扩展方面就是把2改成k,即每k个逆序一次
原题链接Reverse Nodes in k-Group
意思是每k个节点逆序一次,如果不足k个,就不需要改变
方法和上面一样,只是每次逆序k个,然后移动k步。首先计算链表节点总数,每逆序k个就减k,不足k时退出
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseKGroup(ListNode* head, int k) {
if(!head || k <= 1)
return head;
/* 计算链表节点数 */
int n = listLen(head);
ListNode* header = new ListNode(-1);
header->next = head;
ListNode* cur = header;
while(n >= k)
{
/*
* 记录当前节点的下一个节点,从下一个节点开始逆序k个
* 返回逆序后的第一个节点,这个next节点变成第k个节点
* 移动k步
* 总数-k,判断是否还需要继续逆序
*/
ListNode* next = cur->next;
cur->next = kReverse(next, k);
cur = next;
n -= k;
}
ListNode* res = header->next;
delete header;
return res;
}
private:
int listLen(ListNode* head)
{
int n = 0;
while(head)
{
++n;
head = head->next;
}
return n;
}
ListNode* kReverse(ListNode* head, int k)
{
ListNode* cur = head;
ListNode* prv = NULL;
while(k--)
{
ListNode* next = cur->next;
cur->next = prv;
prv = cur;
cur = next;
}
/*
* 这里比较重要,因为逆序后,prv变成第一个节点,head变成最后一个节点
* 此时需要改变head的next指向逆序前的第k+1个节点
* 这个节点正好是cur
*/
head->next = cur;
return prv;
}
};
还有一种方法是通过递归,容易理解些,从当前head开始逆序k个,然后从第k+1开始递归调用当前函数,思路都差不多