143.重排链表
1.先用快慢指针找到链表中点,把后半部分链表反转,再合并两部分链表。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* reverselist(struct ListNode* p)
{
//反转链表
struct ListNode* temp=NULL;
struct ListNode* cur=NULL;
while(p){
temp=p->next;
p->next=cur;
cur=p;
p=temp;
}
return cur;
}
void reorderList(struct ListNode* head){
//用快慢指针把链表拆分成两部分,反转后一个链表,合并链表
struct ListNode* fast=head; // 到链表末尾去
struct ListNode* slow=head;
struct ListNode* p=head;
while(fast && fast->next && fast->next->next)
{
fast=fast->next->next;
slow=slow->next;
}
//反转链表
struct ListNode* revslow=reverselist(slow);
struct ListNode* tmp1=NULL;
struct ListNode* tmp2=NULL;
//合并链表
while(p && revslow){
tmp1=p->next;
tmp2=revslow->next;
p->next=revslow;
p=tmp1;
revslow->next=p;
revslow=tmp2;
}
}
2.递归
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* HeadTail(struct ListNode* head, int len)
{
if(len==1){
struct ListNode* outtail=head->next;
head->next=NULL;
return outtail;
}
if(len==2){
struct ListNode* outtail=head->next->next;
head->next->next=NULL;
return outtail;
}
//递归,找到中间链表的下一个节点,外层链表的尾巴
struct ListNode* tail=HeadTail(head->next,len-2);
//中间链表的头节点
struct ListNode* subhead=head->next;
head->next=tail;
//外层的链表的尾巴
struct ListNode* outtail=tail->next;
tail->next=subhead;
return outtail;
}
void reorderList(struct ListNode* head){
//递归
if(head==NULL || head->next==NULL || head->next->next==NULL) return head;
struct ListNode* p=head;
int len=0;
while(p){
p=p->next;
len++;
}
HeadTail(head,len);
}
21.合并两个有序链表
1.依次比较两个链表的每个值,链接到新的链表上。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2){
int val1=0;
int val2=0;
struct ListNode* newlist=(struct ListNode*)malloc(sizeof(struct ListNode));
newlist->next=NULL;
struct ListNode* newhead=newlist;
while(l1 && l2)
{
val1=l1->val;
val2=l2->val;
if(val1<=val2){
newlist->next=l1;
l1=l1->next;
}
else{
newlist->next=l2;
l2=l2->next;
}
newlist=newlist->next;
}
if(l1){
newlist->next=l1;
}
if(l2){
newlist->next=l2;
}
return newhead->next;
}
2.递归
如果l1的当前值小于l2的当前值,l1->next就等于递归地合并l1->next和l2,另一种情况同理
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2){
if(l1==NULL || l2==NULL){
return l1 ? l1 : (l2 ? l2 : NULL);
}
if(l1->val <= l2->val){
l1->next=mergeTwoLists(l1->next,l2);
return l1;
}
else{
l2->next=mergeTwoLists(l1,l2->next);
return l2;
}
}
160.相交链表
1.两个指针
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
//两个指针分别从A和B的头出发,
//走完自己的一条链表后走另外一条,
//如果相交的话会在交点处相遇
if(headA==NULL || headB==NULL) return NULL;
struct ListNode* p=headA;
struct ListNode* q=headB;
while(p || q){
if(p==q){
return p;
}
p=p->next;
q=q->next;
if(p==NULL && q==NULL){
return NULL;
}
if(p==NULL){
p=headB;
}
if(q==NULL){
q=headA;
}
}
return NULL;
}
有点慢
1290.二进制链表转整数
先求出链表的长度,然后从头开始,计算对应的十进制数。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
int getDecimalValue(struct ListNode* head){
int len=0;
struct ListNode* p=head;
struct ListNode* q=head;
int num=0;
while(p){
p=p->next;
len++;
}
while(q){
num+= (q->val)*pow(2,len-1);
q=q->next;
len--;
}
return num;
}
92.反转链表2
1.常规的反转链表,连接各个部分
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* reverseBetween(struct ListNode* head, int m, int n){
// 找出前一个反转链表的前一个节点和后一个节点,反转的单独反转,再连起来
if(head==NULL) return head;
if(m==n) return head;
struct ListNode* dummy=NULL;
struct ListNode* q=head;
//找到开始反转的节点q和它的前一个节点dummy
while(m>1){
dummy=q;
q=q->next;
m--;
n--;
}
struct ListNode* revtail=q; //反转后的尾部节点
//反转链表
struct ListNode* temp=NULL,*cur=dummy,*p=revtail;
while(n){
temp=p->next;
p->next=cur;
cur=p;
p=temp;
n--;//这样写才可以,如果写成length的话是错的
}
// 反转后,cur是null(如果从第一个开始反转)或反转的第一个结点
if(dummy){
dummy->next=cur;
}
else{
head=cur;
}
revtail->next=p;
return head;
}
2.递归
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* nextnode=NULL;//反转链表的下一个节点
struct ListNode* reverseN(struct ListNode* head, int n){
//反转前n个链表节点
if(n==1){
nextnode=head->next;
return head;
}
struct ListNode* last=reverseN(head->next,n-1);
head->next->next=head;
head->next=nextnode;
return last;//这里怎么返回的last??
}
struct ListNode* reverseBetween(struct ListNode* head, int m, int n){
// 递归
if(m==1){
return reverseN(head,n);
}
head->next=reverseBetween(head->next,m-1,n-1);
return head;
}