C++ LeetCode 链表专题
2020-04-27 07:18
671 查看
文章目录
- LeetCode 206.Reverse Linked List
- LeetCode 92. Reverse Linked List II
- LeetCode 160. Intersection of Two Linked Lists
- LeetCode 141. Linked List Cycle
- LeetCode 142.Linked List Cycle II
- LeetCode 86. Partition List
- LeetCode 21. Merge Two Sorted Lists
LeetCode 206.Reverse Linked List
难度:Easy
方法一:就地逆转
先备份head->next;
再修改head->next;
最后移动head和new_head.
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode* reverseList(ListNode* head) { ListNode*new_head=NULL; while(head){ ListNode*Next=head->next; head->next=new_head; new_head=head; head=Next; } return new_head; } };
方法二:递归
我们首先通过递归确定尾端结点,并进行翻转操作,递归函数逐层返回代表着我已经将你的下一个结点以后的结点都翻转好了,你只需要翻转你和你的下一个结点。t 的值始终为一开始的表尾,最后被用来当做新的表头使用
class Solution { public: ListNode* reverseList(ListNode* head) { if (!head || !head->next) return head; ListNode* t = reverseList(head->next); head->next->next = head; head->next = NULL; return t; } };
方法三:头插法
class solution{ public: ListNode* reverseList(ListNode* head) { ListNode temp_node(0); while(head){ ListNode* Next=head->next; head->next=temp_node.next; temp_node.next=head; head=Next; } return temp_node.next; } }
LeetCode 92. Reverse Linked List II
难度:Medium
方法:先移动head(m-1)个位置,并记录前驱节点pre_head.
记录逆转部分的前节点,也就是逆转后逆转部分的尾节点list_tail.
之后从head开始逆转(n-m+1)个节点.
将list_tail与head对接,再判断prehead是否为空,即m是否为1.
class Solution { public: ListNode* reverseBetween(ListNode* head, int m, int n) { int change_len=n-m+1; ListNode*pre_head=NULL; ListNode*result=head; while(head&&--m){ pre_head=head; head=head->next; } ListNode*list_tail=head; ListNode*temp=NULL; while(head&&change_len--){ ListNode*Next=head->next; head->next=temp; temp=head; head=Next; } list_tail->next=head; if(pre_head){ pre_head->next=temp; } else{ result=temp; } return result; } };
LeetCode 160. Intersection of Two Linked Lists
难度:Easy
方法一:利用STL的set容器。
class Solution { public: ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) { std::set<ListNode*>node_set; while(headA){ node_set.insert(headA); headA=headA->next; } while(headB){ if(node_set.find(headB)!=node_set.end()){ return headB; } headB=headB->next; } return NULL; } };
方法二:两相交的链表,后面一定是一样的,只是前面有长短的区别。
int get_list_len(ListNode*head){ int len=0; while(head){ len++; head=head->next; } return len; } void move_long_list(int a,int b,ListNode*&head){ int len=a-b; while(len){ head=head->next; len--; } } class Solution { public: ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) { int len_a=get_list_len(headA); int len_b=get_list_len(headB); if(len_a>len_b){ move_long_list(len_a,len_b,headA); } else{ move_long_list(len_b,len_a,headB); } while(headA&&headB){ if(headA==headB){ return headA; } headA=headA->next; headB=headB->next; } return NULL; } };
LeetCode 141. Linked List Cycle
难度:Easy
方法一:运用STL的set。
class Solution { public: bool hasCycle(ListNode *head) { std::set<ListNode*>node_set; while(head){ if(node_set.find(head)!=node_set.end()){ return true; } node_set.insert(head); head=head->next; } return false; } };
方法二:快慢指针,有环的话,两指针就一定会相遇。
class Solution { public: bool hasCycle(ListNode *head) { ListNode*slow=head; ListNode*fast=head; while(fast){ slow=slow->next; fast=fast->next; if(!fast){ return false; } fast=fast->next; if(fast==slow) return true; } return false; } };
LeetCode 142.Linked List Cycle II
难度:Medium
方法一:STL的set。
class Solution { public: ListNode *detectCycle(ListNode *head) { std::set<ListNode*>node_set; while(head){ if(node_set.find(head)!=node_set.end()){ return head; } node_set.insert(head); head=head->next; } return NULL; } };
方法二:快慢指针,两指针相遇后,head与meet等速移动,相交点即为环的起始点。
class Solution { public: ListNode *detectCycle(ListNode *head) { ListNode*slow=head; ListNode*fast=head; ListNode*meet=NULL; while(fast){ slow=slow->next; fast=fast->next; if(!fast){ return NULL; } fast=fast->next; if(fast==slow){ meet=fast; break; } } while(meet&&head){ if(meet==head){ return head; } meet=meet->next; head=head->next; } return NULL; } };
LeetCode 86. Partition List
难度:Medium
巧用临时头节点。
不能用指针代替,因为无法传过去,最终是一个空指针。
class Solution { public: ListNode* partition(ListNode* head, int x) { ListNode less_node(0); ListNode more_node(0); ListNode*less_ptr=&less_node; ListNode*more_ptr=&more_node; while(head){ if(head->val<x){ less_ptr->next=head; less_ptr=head; } else{ more_ptr->next=head; more_ptr=head; } head=head->next; } less_ptr->next=more_node.next; more_ptr->next=NULL; return less_node.next; } };
LeetCode 21. Merge Two Sorted Lists
难度:Easy
这个没得说。
class Solution { public: ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { ListNode new_head(0); ListNode*ptr=&new_head; while(l1&&l2){ if(l1->val<l2->val){ ptr->next=l1; l1=l1->next; } else{ ptr->next=l2; l2=l2->next; } ptr=ptr->next; } if(l2){ ptr->next=l2; } if(l1){ ptr->next=l1; } return new_head.next; } };
未完待续。。。
- 点赞
- 收藏
- 分享
- 文章举报
相关文章推荐
- Leetcode 83 删除排序链表中的重复元素 Python C++ 史上最详细题解系列
- leetcode刷题 双向链表 (C++)
- [LeetCode 总结帖]: 链表专题
- leetcode_c++:链表:Merge k Sorted Lists(023)
- leetcode_c++:链表:Reverse Linked Lis(206)
- C++ LeetCode 贪心算法专题
- LeetCode的数组242题和链表25题(C++)
- leetcode_c++:链表:Insertion Sort List(147)
- C++ LeetCode 栈 队列 堆 专题
- leetcode83.删除链表中的重复元素 C++实现
- [C++]LeetCode: 117 Simplify Path (简化Unix路径 list双向链表)
- leetcode_c++:链表:Merge Two Sorted Lists(021)
- [C++]LeetCode 21: Merge Two Sorted Lists(合并链表)
- LeetCode排序链表C++版
- leetcode_效率题解_[python/C++]_21. Merge Two Sorted Lists(合并2个有序链表)
- leetcode_c++:链表:Partition List (086)
- leetcode_c++:链表:Sort List(148)
- leetcode_c++:链表:Palindrome Linked List(234)
- [C++]LeetCode: 102 Flatten Binary Tree to Linked List (二叉树转前序链表)
- Leetcode刷题14-237.删除链表中的节点(C++)