反转链表
定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。
示例:
输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL
限制:
0 <= 节点个数 <= 5000
题解:头插法,将后边的结点依次插入到头结点与第一个结点之间
class Solution {
public:
ListNode* fun(ListNode* rt){
if(rt==NULL) return NULL; // rt为空
ListNode* root=new ListNode(-1);
root->next=rt;
ListNode* l=rt; ListNode* r=rt->next;
if(r==NULL) return rt; // rt链表只有一个结点
ListNode* p=l;
while(r){
p->next=r->next;
root->next=r;
r->next=l;
r=p->next;
l=root->next;
}
return root->next;
}
ListNode* reverseList(ListNode* head) {
return fun(head);
}
};
重排链表
给定一个单链表 L:L0→L1→…→Ln-1→Ln ,
将其重新排列后变为: L0→Ln→L1→Ln-1→L2→Ln-2→…
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
示例 1:
给定链表 1->2->3->4, 重新排列为 1->4->2->3.
示例 2:
给定链表 1->2->3->4->5, 重新排列为 1->5->2->4->3.
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/reorder-list
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题解:将整个链表拆分成两个链表 rt1(前半部分) 与 rt2(后半部分),将rt2链表进行反转,依次合并两个链表
class Solution {
public:
ListNode* fun(ListNode* rt){ // 反转链表
if(rt==NULL) return NULL; // rt为空
ListNode* root=new ListNode(-1);
root->next=rt;
ListNode* l=rt; ListNode* r=rt->next;
if(r==NULL) return rt; // rt链表只有一个结点
ListNode* p=l;
while(r){
p->next=r->next;
root->next=r;
r->next=l;
r=p->next;
l=root->next;
}
return root->next;
}
void reorderList(ListNode* rt) {
int len=0;
ListNode* root=rt;
while(root){
len++;
root=root->next;
}
if(!len||len<=2) return ;
int num=1,index=0;
if(len&1) index=len/2+1;
else index=len/2;
ListNode* rt1=rt; ListNode* rt2=rt->next; ListNode* l=rt;
while(num<index){ // 拆分链表
l=l->next;
rt2=rt2->next;
num++;
}
l->next=NULL;
rt2=fun(rt2); // 翻转链表
while(rt2){ // 合并链表
ListNode* r=rt1->next;
if(r==NULL){
rt1->next=rt2;
break;
}
ListNode* rr=rt1->next;
ListNode* p=rt2;
rt2=rt2->next;
rt1->next=p;
p->next=rr;
rt1=rr;
}
}
};