链表题目总结
ACW34.链表环的入口结点
解法一:快慢指针
可以用公式来说明:a,b,c,x,y的含义同上,我们用 z 表示从 c 点顺时针走到 b 的距离。则第一次相遇时 second 所走的距离是 x+(y+z)∗n+y, n 表示圈数,同时 second走过的距离是 first的两倍,也就是 2(x+y),所以我们有 x+(y+z)∗n+y=2(x+y),所以 x=(n−1)×(y+z)+z。那么我们让 second 从 cc 点开始走,走 x 步,会恰好走到 b 点;让 first 从 a 点开始走,走 x 步,也会走到 b 点。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *entryNodeOfLoop(ListNode *head) {
if(!head || !head->next){
return head;
}
ListNode * fast = head, * last = head;
while(fast && last){
fast = fast->next;
last = last->next;
if(fast){
fast = fast->next;
}else{
return NULL;
}
if(fast == last){
fast = head;
while(fast != last){
fast = fast->next;
last = last->next;
}
return fast;
}
}
}
};
解法二:数组判重
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *entryNodeOfLoop(ListNode *head) {
if(!head || !head->next){
return head;
}
ListNode * dummy = head;
bool st[10005] = {};
while(dummy){
if(!st[dummy->val]){
st[dummy->val] = true;
dummy = dummy->next;
}else{
break;
}
}
return dummy;
}
};
ACW1451单链表快速排序
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode * get_tail(ListNode *head){
while(head->next){
head = head->next;
}
return head;
}
ListNode* quickSortList(ListNode* head) {
if(!head||!head->next){
return head;
}
ListNode *left = new ListNode(-1), *mid = new ListNode(-1), * right = new ListNode(-1);
ListNode * ltail = left, *mtail = mid, *rtail = right;
auto val = head->val;
for(auto p = head; p; p = p->next){
if(p->val < val){
ltail = ltail->next = p;
}else if( p->val == val){
mtail = mtail->next = p;
}else{
rtail = rtail->next = p;
}
}
ltail->next = mtail->next = rtail->next = NULL;
left->next = quickSortList(left->next);
right->next = quickSortList(right->next);
get_tail(left)->next = mid->next;
get_tail(left)->next = right->next;
return left->next;
}
};
ACW35反转链表
迭代版本
/**
* 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 * pre = NULL,*cur = head;
while(cur){
ListNode* ne = cur->next;
cur->next = pre;
pre = cur;
cur = ne;
}
return pre;
}
};
递归版本
/**
* 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) {
if(!head || !head->next){
return head;
}
auto res = reverseList(head->next);
head->next->next = head;
head->next = NULL;
return res;
}
};
lc82. 删除排序链表中的重复元素 II
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode deleteDuplicates(ListNode head) {
ListNode dummy = new ListNode(-1);
dummy.next = head;
ListNode p = dummy;
while(p.next != null){
ListNode q = p.next;
while(q.next!=null&&q.next.val==p.next.val){
q=q.next;
}
if(q == p.next){
p = q;
}else{
p.next = q.next;
}
}
return dummy.next;
}
}
lc 83. 删除排序链表中的重复元素
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode deleteDuplicates(ListNode head) {
ListNode dummy = new ListNode(0,head);
while(head!=null&&head.next!=null){
if(head.val ==head.next.val){
head.next = head.next.next;
}else{
head = head.next;
}
}
return dummy.next;
}
}
lc19. 删除链表的倒数第 N 个结点
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode * pre = new ListNode(0,head);
ListNode * cur = pre;
int cnt = 0;
while(head){
cnt++;
head = head->next;
}
for(int i = 0; i < cnt-n; i++){
cur = cur->next;
}
cur->next = cur->next->next;
return pre->next;
}
};