leetcode_链表总结

来源:互联网 发布:手机mac地址不可用 编辑:程序博客网 时间:2024/06/11 08:25

206.Reverse Linked List

Reversea singly linked list

链表反向;

思路:定义一个个新链表的临时节点,依次遍历链表的每个节点,每遍历一个节点就逆置一个节点。

























































针对一次循环要做的操作如下:

1.定义一个新指针为new_head,初始化为NULL

2.定义一个临时指针next用来备份head->next,即next=head->next,以备下次循环时使用。

3.现在修改当前head->next使得指向新节点。head->next=newhead,然后讲newhead指针向前移动一个newhead=head;最后将head更新为初始备份的next

返回新链表的头结点newhead.



目的是返回新链表的头结点new_head

/**

*Definition for singly-linked list.

*struct ListNode {

* int val;

* ListNode *next;

* ListNode(int x) : val(x), next(NULL) {}

*};

*/

classSolution {

public:

ListNode*reverseList(ListNode* head) {

ListNode*newhead=NULL;

while(head){

ListNode*next=head->next;

head->next=newhead;

newhead=head;

head=next;

}

returnnewead;

}

};


92.Reverse Linked List II






































classSolution {

public:

ListNode*reverseBetween(ListNode* head, int m, int n) {

intchangelen=n-m+1;//mn总共要改变的节点个数为n-m+1

ListNode*result=head; //如果不是从第一个节点开始逆序。一般情况下返回的新链表头结点为当前节点的head,先把它保存起来。

ListNode*pre=NULL;//定义一个前驱节点为pre

while(head&&--m){//从第m个节点开始逆序,那么只要移动m-1次,pre是前一个head的前驱,head指向第m个节点,即逆序之后的尾节点。

pre=head;

head=head->next;

}

ListNode*modify_tail=head;

ListNode*newhead=NULL;//定义从第m个节点开始的逆序初始节点为NULL

while(head&&changelen--){

ListNode*next=head->next;

head->next=newhead;

newhead=head;

head=next;//在最后一次循环结束之后head已经指向第n+1个节点

}

modify_tail->next=head;//可以直接将逆序之后的尾节点指向第n+1个节点。

if(pre){

pre->next=newhead;//如果pre不为空,则需将prenewhead连接起来。

}

else{

result=newhead;//如果pre为空,则表明从第一个节点开始逆序,直接返回newhead即为新链表的头结点。

}

returnresult;

}

};



160.Intersection of Two Linked Lists

求两个链表的交点


















方法一采用STL库中的set集合

/**

*Definition for singly-linked list.

*struct ListNode {

* int val;

* ListNode *next;

* ListNode(int x) : val(x), next(NULL) {}

*};

*/

classSolution {

public:

ListNode*getIntersectionNode(ListNode *headA, ListNode *headB) {

std::set<ListNode*>node_set;

while(headA){

node_set.insert(headA);//headA的指针加入到节点集合中。

headA=headA->next;

}

while(headB){

if(node_set.find(headB)!=node_set.end()){//如果在node_set中找到的不是最后一个则返回.

returnheadB;

}

headB=headB->next;

}

returnNULL;

}

};


方法二



















classSolution {

public:

ListNode*getIntersectionNode(ListNode *headA, ListNode *headB) {

intListA_len=get_list_node(headA);

intListB_len=get_list_node(headB);

if(ListA_len>ListB_len){

headA=forward_long(ListA_len,ListB_len,headA);

}

else{

headB=forward_long(ListB_len,ListA_len,headB);

}

while(headA&&headB){

if(headA==headB){

returnheadA;

}

headA=headA->next;

headB=headB->next;

}

returnNULL;

}

intget_list_node(ListNode *head){//定义求长度的函数

intlen=0;

while(head){

len++;

head=head->next;

}

returnlen;

}

ListNode*forward_long(int long_len,int short_len,ListNode*head){//定义移动相同长度的节点位置函数

intdelta=long_len-short_len;

while(head&&delta--){

head=head->next;

}

returnhead;

}

};


142.Linked List Cycle II


















classSolution {

public:

ListNode*detectCycle(ListNode *head) {

std::set<ListNode*> node_set;

while(head){

node_set.insert(head);

head=head->next;

if(node_set.find(head)!=node_set.end()){

returnhead;

}

}

returnNULL;

}

};









































classSolution {

public:

ListNode*detectCycle(ListNode *head) {

ListNode*slow=head;//定义慢节点

ListNode*fast=head;//定义快节点

ListNode*meet=NULL;//定义相遇节点并初始化为NULL

while(fast){

slow=slow->next;

fast=fast->next;

if(!fast){//如果fast遇到链尾,或者链表为空链表,表明没有环返回NULL

returnNULL;

}

fast=fast->next;

if(fast==slow){

meet=fast;//fastslow相遇,则返回相遇链表节点

break;

}

}

if(meet==NULL){

returnNULL;//如果没有相遇,则表明没有环

}

while(meet){

if(head==meet){

returnhead;

}

head=head->next;

meet=meet->next;

}

}

};


86.Partition List













































































注意头结点和头指针的区别。用临时头节点,定义两个临时头节点less_head(0),more_head(0),并使初值为0,初始的less_head.next=NULL,more_head=NULL,即初始情况下指向下一节点的指针next存储为NULL。定义两个临时指针指向两个头节点。less_ptr->next是指将该指针对应的节点的位置域重新赋值。





















classSolution {

public:

ListNode*partition(ListNode* head, int x) {

ListNodeless_head(0);//设置两个临时头结点less_head(0)more_head(0)

ListNodemore_head(0);

ListNode*less_ptr=&less_head;//定义两个指针,让个分别指向两个临时头结点

ListNode*more_ptr=&more_head;

while(head){

if(head->val<x){

less_ptr->next=head;//更新less_ptr

less_ptr=head;

}

else{

more_ptr→next=head;//更新more_ptr

more_ptr=head;

}

head=head->next;

}

less_ptr→next=more_head.next;//将连个链表连接起来,将less_ptr-next指向此前定义的more_head节点的next位置域。more_head节点的next位置域存储着下一节点的地址。

more_ptr->next=NULL;//将尾节点的位置域赋值为NULL,使其成为为节点

returnless_head.next;//返回头结点less_head.next位置域指向的下一节点作为新链表的头指针

}

};