链表基础css
链表(Linked List)相比数组(Array),物理存储上非连续、不支持O(1)时间按索引存取;但链表也有其优势,灵活的内存管理、容许在链表任意位置上插入和删除节点。单向链表结构通常以下:node
//Definition for singly-linked list. struct ListNode { int val; ListNode *next; ListNode(int x) : val(x), next(NULL) {} };
相关LeetCode题:git
707. Design Linked List 题解github
链表增删改查数组
要完成链表节点的查找、插入、删除与修改,须要特别留意先后指针的修改、空指针的处理。总得来讲链表增删改查分三步:1/定义结束条件(通常为到达链表尾) 2/遍历链表 3/遍历过程当中完成增删改查。spa
一些状况下会用哑节点(dummy node)来更方便对链表增删改查,这有时能够减小代码量。好比 LeetCode题目 203. Remove Linked List Elements:3d
// 203. Remove Linked List Elements ListNode* removeElements(ListNode* head, int val) { ListNode* dummy=new ListNode(0); dummy->next=head; ListNode* cur=dummy; while(cur->next!=NULL){ if(cur->next->val==val) cur->next=cur->next->next; else cur=cur->next; } return dummy->next; }
以上若是不使用dummy node,若是head是要被删除的节点,则须要特殊判断和处理,使用dummy node则化解了这个问题。 指针
相关LeetCode题:code
203. Remove Linked List Elements 题解component
876. Middle of the Linked List 题解
83. Remove Duplicates from Sorted List 题解
82. Remove Duplicates from Sorted List II 题解
1019. Next Greater Node In Linked List 题解
1171. Remove Zero Sum Consecutive Nodes from Linked List 题解
也能够用递归的方式遍历链表,但这种方式会重复访问节点,时间复杂度比O(n)高不少。
相关LeetCode题:
反转/旋转链表
反转(reverse)链表与旋转(rotate)链表是考量链表操做的经典题目,最是考验作题人对链表节点逻辑关系的了解程度和是否能灵活处理指针。
相关LeetCode题:
25. Reverse Nodes in k-Group 题解
环形链表
处理环形链表问题,经常用到双指针(Two Pointers)、快慢指针,例如 LeetCode题目 141. Linked List Cycle:
// 141. Linked List Cycle bool hasCycle(ListNode *head) { if(head==NULL) return false; ListNode* p=head; ListNode* pp=head; while(pp->next!=NULL&&pp->next->next!=NULL){ p=p->next; pp=pp->next->next; if(p==pp) return true; } return false; }
相关LeetCode题:
708. Insert into a Cyclic Sorted List 题解
多链表处理
多链表的增删改、合并,与单链表的处理方式同样,只是增长了对多个链表的遍历。
相关LeetCode题:
160. Intersection of Two Linked Lists 题解
链表排序
对链表进行排序通常指原址排序,即修改节点指针指向、而不修改节点的值。对链表进行归并排序(Merge Sort),平均时间复杂度为O(nlogn),相比其余排序方法,归并排序在平均时间复杂度上是较优的方法。
相关LeetCode题: