赞
踩
8.链表的环
仿照快慢指针求解中间节点,注意单独处理k>链表表长的情况
- struct ListNode* getKthFromEnd(struct ListNode* head, int k)
- {
- struct ListNode*fast,*slow;
- fast=slow=head;
-
- //fast先走k步
- while(k--)
- {
- //表长小于k,则fast为空
- if(fast==NULL)
- {
- return NULL;
- }
- else
- {
- fast=fast->next;
- }
-
- }
-
- //fast slow一起走
- while(fast)
- {
- fast=fast->next;
- slow=slow->next;
- }
- return slow;
- }
题目描述
方法:归并
从头比较,取小的尾插到新链表,当有一个链表为空时,结束。
- struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2)
- {
- if(l1==NULL)
- return l2;
- if(l2==NULL)
- return l1;
-
- struct ListNode*head,*tail;
- head=tail=NULL;
- while(l1&&l2)
- {
- if(l1->val<l2->val)
- {
- if(tail==NULL)
- {
- head=tail=l1;
- }
- else
- {
- tail->next=l1;
- tail=tail->next;
- }
- l1=l1->next;
- }
- else
- {
- if(tail==NULL)
- {
- head=tail=l2;
- }
- else
- {
- tail->next=l2;
- tail=tail->next;
- }
- l2=l2->next;
- }
- }
- if(l1)
- {
- tail->next=l1;
- }
- if(l2)
- {
- tail->next=l2;
- }
- return head;
- }
上面这种也可以加一个带哨兵位的头节点,这样就不用判断tail是否为空的情况,开头的那段判断也可以不用
- struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2)
- {
-
- struct ListNode*head,*tail;
- head=tail=(struct ListNode*)malloc(sizeof( struct ListNode));
- tail->next=NULL;
- while(l1&&l2)
- {
- if(l1->val<l2->val)
- {
-
- tail->next=l1;
- tail=tail->next;
-
- l1=l1->next;
- }
- else
- {
- tail->next=l2;
- tail=tail->next;
-
- l2=l2->next;
- }
- }
- if(l1)
- {
- tail->next=l1;
- }
- if(l2)
- {
- tail->next=l2;
- }
- struct ListNode*list=head->next;
- free(head);
- return list;
- }
题目描述
思路:设置两个带哨兵位的头节点的链表,一个储存比x大的数据,一个储存比x小的数据,最后将两个链表链接起来
- /**
- * Definition for singly-linked list.
- * struct ListNode {
- * int val;
- * struct ListNode *next;
- * };
- */
-
-
- struct ListNode* partition(struct ListNode* head, int x){
- //产生两个带哨兵位的头节点
- struct ListNode*lesshead,*lesstail,*greaterhead,*greatertail;
- lesshead=lesstail=(struct ListNode*)malloc(sizeof(struct ListNode));
- lesstail->next=NULL;
- greaterhead=greatertail=(struct ListNode*)malloc(sizeof(struct ListNode));
- greatertail->next=NULL;
-
- struct ListNode*cur=head;
- while(cur)
- {
- if(cur->val<x)
- {
- //插入less
- lesstail->next=cur;
- lesstail=lesstail->next;
- }
- else
- {
- //插入greater
- greatertail->next=cur;
- greatertail=greatertail->next;
- }
- cur=cur->next;
- }
- //链接两个链表
- lesstail->next=greaterhead->next;
- greatertail->next=NULL;//可以避免链表成环问题
-
- struct ListNode*newhead=lesshead->next;
- free(greaterhead);
- free(lesshead);
-
- return newhead;
-
- }
题目描述
思路:
1.找到中间节点
2.将后半段逆置
3.依次比较
8.相交链表
题目描述思路:
1.容易发现若两个链表相交,则他们一定有共同的尾节点因为节点的next只能有一个位置
2.主要问题在于保持其原本结构《==》破坏后要恢复
方法
求A的长度lenA,求B的长度lenB.长的A先走差距步,
- struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
- if(headA==NULL||headB==NULL)
- return NULL;
-
- struct ListNode *curA=headA;
- struct ListNode *curB=headB;
- int lenA=1,lenB=1;
- //求表A的长同时找到A的尾节点
- while(curA)
- {
- curA=curA->next;
- lenA++;
- }
-
- //求表B的长同时找到B的尾节点
- while(curB)
- {
- curB=curB->next;
- lenB++;
- }
-
- if(curA!=curB)
- return NULL;
-
- //求第一个交点
- //假设A是短链表,B是长链表
- struct ListNode *shortlist=headA;struct ListNode *longlist=headB;
- //修正
- if(lenA>lenB)
- {
- longlist=headA;
- shortlist=headB;
- }
-
- //长的先走gap步
- int gap=abs(lenA-lenB);
- while(gap--)
- {
- longlist=longlist->next;
- }
-
- //一起后移
- while(shortlist!=longlist)
- {
- longlist=longlist->next;
- shortlist=shortlist->next;
- }
- return shortlist;
- }
思路:类比位移追及问题
- bool hasCycle(struct ListNode *head)
- {
- struct ListNode *fast,*slow;
- fast=slow=head;
- while(fast&&fast->next)
- {
- fast=fast->next->next;
- slow=slow->next;
- if(fast==slow)
- return true;
- }
- return false;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。