一、

1. Remove Duplicates from Sorted List II

 class Solution {
public:
ListNode* deleteDuplicates(ListNode* head) {
ListNode* dummy = new ListNode();
dummy->next = head;
ListNode* pre = dummy;
ListNode* cur = head;
while (cur != NULL && cur->next != NULL) {
if (cur->val == cur->next->val) {
while(cur->next != NULL && cur->val == cur->next->val) {
cur = cur->next;
}
pre->next = cur->next;
cur = cur->next;
} else {
pre = pre->next;
cur = cur->next;
}
}
return dummy->next;
}
};

2. Remove Duplicates from Sorted List

 class Solution {
public:
ListNode* deleteDuplicates(ListNode* head) {
ListNode* dummy = new ListNode();
dummy->next = head;
ListNode* pre = dummy, *cur = head;
while (cur != NULL && cur->next != NULL) {
if (cur->val == cur->next->val) {
while (cur->next != NULL && cur->val == cur->next->val) {
cur = cur->next;
}
pre->next = cur;
pre = pre->next;
cur = cur->next;
} else {
cur = cur->next;
pre = pre->next;
}
}
return dummy->next;
}
};

只在1.的基础上改了两句。

二、

1. Reverse Linked List 【模板式】

 ListNode* reverseList(ListNode* head) {
ListNode* prev = NULL;
while (head != NULL) {
ListNode* next = head->next;
head->next = prev;
prev = head;
head = next;
}
return prev;
}

while循环里和swap很像,上一句的右侧都是下一句的左侧。

2. Reverse Linked List II

 class Solution {
public:
ListNode* reverseBetween(ListNode* head, int m, int n) {
ListNode* dummy = new ListNode();
dummy->next = head;
ListNode* prev = dummy;
for (int i = ; i < m; i++) {
prev = prev->next;
}
head = prev->next;
ListNode* next = head->next;
ListNode* pprev = prev;
ListNode* tail = head;
for (int i = m; i <= n; i++) { //这部分和reverseList一样
next = head->next;
head->next = prev;
prev = head;
head = next;
}
pprev->next = prev;
tail->next = head;
return dummy->next;
}
};

中间(m, n)区间内reverse和1.里reverseList一样。

注意:从m到n这几个元素都参与for循环了,包括第m个元素!进行reverse之后,head指向第n+1个元素,prev指向逆转后的新head(从m到n这几个元素中的新head)。

Partition List

 class Solution {
public:
ListNode* partition(ListNode* head, int x) {
ListNode* leftDummy = new ListNode();
ListNode* rightDummy = new ListNode();
ListNode* left = leftDummy, *right = rightDummy;
while (head != NULL) {
if (head->val < x) {
left->next = head;
left = left->next;
} else {
right->next = head;
right = right->next;
}
head = head->next;
}
right->next = NULL;
left->next = rightDummy->next;
return leftDummy->next;
}
};

Merge Two Sorted Lists

 class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
ListNode* dummy = new ListNode();
ListNode* pre = dummy;
while (l1 != NULL && l2 != NULL) {
if (l1->val < l2->val) {
pre->next = l1;
l1 = l1->next;
} else {
pre->next = l2;
l2 = l2->next;
}
pre = pre->next;
}
if (l1 != NULL) {
pre->next = l1;
}
if (l2 != NULL) {
pre->next = l2;
}
return dummy->next;
}
};

Sort List

用MergeSort和QuickSort分别实现一下。

MergeSort用到了findMedian的方法(利用双指针可以达到one-pass找到中点)。

 class Solution {
public:
ListNode* findMiddle(ListNode* head) { // 找到的是下标为(n - 1) / 2的点(如果是偶数个数,那就是中间偏左一点的)
ListNode* slow = head, *fast = head->next;
while (fast != NULL && fast->next != NULL) {
slow = slow->next;
fast = fast->next->next;
}
return slow;
}
ListNode* merge(ListNode* l1, ListNode* l2) {
ListNode* dummy = new ListNode();
ListNode* pre = dummy;
while (l1 != NULL && l2 != NULL) {
if (l1->val < l2->val) {
pre->next = l1;
l1 = l1->next;
} else {
pre->next = l2;
l2 = l2->next;
}
pre = pre->next;
}
if (l1 != NULL) {
pre->next = l1;
}
if (l2 != NULL) {
pre->next = l2;
}
return dummy->next;
} ListNode* sortList(ListNode* head) {
if (head == NULL || head->next == NULL) {
return head;
}
ListNode* mid = findMiddle(head);
ListNode* right = sortList(mid->next);
mid->next = NULL;
ListNode* left = sortList(head);
return merge(left, right);
}
};

其中merge即为上一题中的mergeTwoLists.

注意:findMiddle函数最开始时slow = head, fast = head->next. 通过这种方式可以保证求出来的mid是当有偶数个元素时是中间偏左一点的。

Reorder List

【三大链表基本操作:findMiddle,reverse,merge】

 class Solution {
public:
ListNode* findMiddle(ListNode* head) {
ListNode* slow = head, *fast = head;
while (fast != NULL && fast->next != NULL) {
slow = slow->next;
fast = fast->next->next;
}
return slow;
}
ListNode* reverseList(ListNode* head) {
ListNode* prev = NULL;
while (head != NULL) {
ListNode* next = head->next;
head->next = prev;
prev = head;
head = next;
}
return prev;
}
ListNode* merge(ListNode* l1, ListNode* l2) {
ListNode* dummy = new ListNode();
ListNode* prev = dummy;
int count = ;
while (l1 != NULL && l2 != NULL) {
count++;
if (count % == ) {
prev->next = l1;
l1 = l1->next;
} else {
prev->next = l2;
l2 = l2->next;
}
prev = prev->next;
}
if (l1 != NULL) {
prev->next = l1;
} else {
prev->next = l2;
}
return dummy->next;
}
void reorderList(ListNode* head) {
if (head == NULL || head->next == NULL) {
return;
}
ListNode* mid = findMiddle(head);
ListNode* p = reverseList(mid->next);
mid->next = NULL;
merge(head, p);
}
};

Merge k Sorted Lists

方法1: 利用堆(priority_queue)。每次取出K个队列中的最小值(logK),共取N次,因此复杂度为 NlogK

 class Solution {
public:
struct cmp {
bool operator()(ListNode* p, ListNode* q) {
return p->val > q->val;
}
}; ListNode* mergeKLists(vector<ListNode*> &lists) {
if (lists.empty()) {
return NULL;
}
priority_queue<ListNode*, vector<ListNode*>, cmp> pq;
ListNode* dummy = new ListNode();
ListNode* prev = dummy;
for (int i = ; i < lists.size(); i++) {
if (lists[i] != NULL) {
pq.push(lists[i]);
}
}
while (!pq.empty()) {
ListNode* tmp = pq.top();
prev->next = tmp;
prev = tmp;
pq.pop();
if (tmp->next != NULL) {
pq.push(tmp->next);
}
}
return dummy->next;
}
};

方法2:分治。【自顶向下】

 class Solution {
public:
ListNode* mergeKLists(vector<ListNode*> &lists) {
if (lists.empty()) {
return NULL;
}
return mergeHelper(lists, , lists.size() - );
} ListNode* mergeHelper(vector<ListNode*> &lists, int start, int end) {
if (start == end) {
return lists[start];
}
int mid = start + (end - start) / ;
ListNode* left = mergeHelper(lists, start, mid);
ListNode* right = mergeHelper(lists, mid + , end);
return mergeTwoLists(left, right);
} ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
ListNode* dummy = new ListNode();
ListNode* prev = dummy;
while (l1 != NULL && l2 != NULL) {
if (l1->val < l2->val) {
prev->next = l1;
l1 = l1->next;
} else {
prev->next = l2;
l2 = l2->next;
}
prev = prev->next;
}
if (l1 != NULL) {
prev->next = l1;
} else {
prev->next = l2;
}
return dummy->next;
}
};

注意:不要忘了判空!这种边界条件要谨慎!谨记!

Linked List Cycle

 class Solution {
public:
bool hasCycle(ListNode* head) {
if (head == NULL) {
return false;
}
ListNode* slow = head, *fast = head;
while (fast && fast->next) {
slow = slow->next;
fast = fast->next->next;
if (slow == fast) {
return true;
}
}
return false;
}
};

Linked List Cycle II

 class Solution {
public:
ListNode* detectCycle(ListNode* head) {
ListNode* slow = head, *fast = head;
while (fast && fast->next) {
slow = slow->next;
fast = fast->next->next;
if (slow == fast) {
while (head != slow) {
head = head->next;
slow = slow->next;
}
return slow;
}
}
return NULL;
}
};

Copy List with Random Pointer

 class Solution {
public: void copyNext(RandomListNode* head) {
RandomListNode* pre = head;
while (pre != NULL) {
RandomListNode* tmp = new RandomListNode(pre->label);
tmp->next = pre->next;
pre->next = tmp;
pre = pre->next->next;
}
}
void copyRandom(RandomListNode* head) {
RandomListNode* pre = head;
while (pre != NULL) {
if (pre->random != NULL) { // don't forget
pre->next->random = pre->random->next;
}
pre = pre->next->next;
}
} RandomListNode* splitList(RandomListNode* head) {
RandomListNode* newHead = head->next;
RandomListNode* q = newHead;
while (head != NULL) {
head->next = q->next;
head = head->next;
if (head) { // don't forget
q->next = head->next;
}
q = q->next;
}
return newHead;
} RandomListNode* copyRandomList(RandomListNode* head) {
if (head == NULL) {
return NULL;
}
copyNext(head);
copyRandom(head);
return splitList(head);
}
};

注意!处理链表题很重要的一点是:在对一个指针p取next时,首先要确保 p!=NULL 

Clone Graph

Convert Sorted List to Binary Search Tree

Convert Binary Tree to Doubly Linked List

Reverse Nodes in k-Group

Heapify 堆化

=================================================

  24 Swap Nodes in Pairs 32.4% Medium
  148 22.2% Medium
  61 Rotate List 21.7% Medium
  25 25.4% Hard
  206   31.9% Easy
  92   26.0% Medium
  143   21.0% Medium
  19 Remove Nth Node From End of List 27.0% Easy
  203 Remove Linked List Elements 25.9% Easy
  83   34.5% Easy
  82   25.0% Medium
  86   27.4% Medium
  234 Palindrome Linked List 22.6% Easy
  21   32.6% Easy
  23 21.1% Hard
  141   36.3% Medium
  142   31.4% Medium
  160 Intersection of Two Linked Lists 28.7% Easy
  147 Insertion Sort List 26.6% Medium
  237 Delete Node in a Linked List 46.7% Easy
  138 25.2% Hard
  109 27.9% Medium
  2 Add Two Numbers 20.7% Medium

[剑指offer] 两个链表的第一个公共节点

 class Solution {
public:
ListNode* FindFirstCommonNode(ListNode* pHead1, ListNode* pHead2) {
ListNode* p = pHead1;
int count1 = , count2 = ;
while (p != NULL) {
count1++;
p = p->next;
}
p = pHead2;
while (p != NULL) {
count2++;
p = p->next;
}
if (count1 < count2) {
return findNode(pHead1, count1, pHead2, count2);
} else {
return findNode(pHead2, count2, pHead1, count1);
}
} ListNode* findNode(ListNode* pHead1, int count1, ListNode* pHead2, int count2) {
if (pHead1 == NULL) {
return NULL;
}
int tmp = count2 - count1;
ListNode* p2 = pHead2, *p1 = pHead1;
while (tmp--) {
p2 = p2->next;
}
while (p1 != NULL && p1 != p2) {
p1 = p1->next;
p2 = p2->next;
}
return p1;
}
};

参考剑指offer P193. 本题说的“公共节点”不是指“值相等”,而是“同一个节点”。即两链表在该点处汇合。

leetcode Ch5-Linked List的更多相关文章

  1. 【Leetcode】Linked List Cycle II

    Given a linked list, return the node where the cycle begins. If there is no cycle, return null. Foll ...

  2. [LeetCode] 141. Linked List Cycle 链表中的环

    Given a linked list, determine if it has a cycle in it. Follow up:Can you solve it without using ext ...

  3. [LeetCode] 142. Linked List Cycle II 链表中的环 II

    Given a linked list, return the node where the cycle begins. If there is no cycle, return null. Foll ...

  4. [LeetCode] Palindrome Linked List 回文链表

    Given a singly linked list, determine if it is a palindrome. Follow up: Could you do it in O(n) time ...

  5. [LeetCode] Reverse Linked List 倒置链表

    Reverse a singly linked list. click to show more hints. Hint: A linked list can be reversed either i ...

  6. [LeetCode] Remove Linked List Elements 移除链表元素

    Remove all elements from a linked list of integers that have value val. Example Given: 1 --> 2 -- ...

  7. [LeetCode] Reverse Linked List II 倒置链表之二

    Reverse a linked list from position m to n. Do it in-place and in one-pass. For example:Given 1-> ...

  8. Java for LeetCode 142 Linked List Cycle II

    Given a linked list, return the node where the cycle begins. If there is no cycle, return null. Foll ...

  9. [LeetCode] Split Linked List in Parts 拆分链表成部分

    Given a (singly) linked list with head node root, write a function to split the linked list into k c ...

  10. [LeetCode] Design Linked List 设计链表

    Design your implementation of the linked list. You can choose to use the singly linked list or the d ...

随机推荐

  1. AngularJS Eclipse Plugin

    本文介绍如何安装和配置 AngularJS Eclipse.AngularJS Eclipse 插件是基于强大的 JavaScript 推断引擎(javascript inference engine ...

  2. PHP之mb_convert_case使用

    mb_convert_case (PHP 4 >= 4.3.0, PHP 5, PHP 7) mb_convert_case - Perform case folding on a string ...

  3. maven在pom文件中添加你想要的jar包

    概述:POM 文件里面的依赖jar包经常需要添加, 仅需要在google中代码查找 :maven 你需的jar包名称 repository 用了Maven,所需的JAR包就不能再像往常一样,自己找到并 ...

  4. Training Logisches Denken

    1.Das Begriff 1.1 Die Arten von Begriff 1.1.1 alleines Begriff,universales Begriff,Leeres Begriff: A ...

  5. 人脸识别(基于Caffe)

    人脸识别(基于Caffe, 来自tyd) 人脸识别(判断是否为人脸) LMDB(数据库, 为Caffe支持的分类数据源) mkdir face_detect cd face_detect mkdir ...

  6. spring cloud连载第二篇之Spring Cloud Config

    Spring Cloud Config Spring Cloud Config为分布式服务提供了服务侧和客户侧的外部配置支持.通过Spring Cloud Config你可以有一个统一的地方来管理所有 ...

  7. JavaScript的原型链继承__propt__、prototype、constructor的理解、以及他们之间相互的关系。

    回想自己已经工作了有一段时间了,但是自己对JavaScript的原型链.和继承的理解能力没有到位,最近他们彻底的整理并且复习了一遍. 本案例中部分文案来自网络和书籍,如有侵权请联系我,我只是把我的理解 ...

  8. AJAX 教程

    AJAX AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML). AJAX 不是新的编程语言,而是一种使用现有标准的新方法. AJA ...

  9. Bundle传递数据,Handler更新UI

    Bundle主要用于传递数据:它保存的数据,是以key-value(键值对)的形式存在的. Bundle经常使用在Activity之间或者线程间传递数据,传递的数据可以是boolean.byte.in ...

  10. 一:Java基础

    /-- 第一章:概念 --/ 1.java特点:跨平台.面向对象.开源 2.JVM是Java虚拟机的缩写,可以实现跨平台 3.java运行原理: 1).编写java源文件,以.java作为后缀名 2) ...