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;//从m到n总共要改变的节点个数为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不为空,则需将pre和newhead连接起来。
}
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;//fast与slow相遇,则返回相遇链表节点
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位置域指向的下一节点作为新链表的头指针
}
};