leetcode Ch5-Linked List
一、
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很像,上一句的右侧都是下一句的左侧。
- 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)。
- 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;
- }
- };
- 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;
- }
- };
用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是当有偶数个元素时是中间偏左一点的。
【三大链表基本操作: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);
- }
- };
方法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;
- }
- };
注意:不要忘了判空!这种边界条件要谨慎!谨记!
- 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;
- }
- };
- 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;
- }
- };
- 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
Convert Sorted List to Binary Search Tree
Convert Binary Tree to Doubly Linked List
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的更多相关文章
- 【Leetcode】Linked List Cycle II
Given a linked list, return the node where the cycle begins. If there is no cycle, return null. Foll ...
- [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 ...
- [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 ...
- [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 ...
- [LeetCode] Reverse Linked List 倒置链表
Reverse a singly linked list. click to show more hints. Hint: A linked list can be reversed either i ...
- [LeetCode] Remove Linked List Elements 移除链表元素
Remove all elements from a linked list of integers that have value val. Example Given: 1 --> 2 -- ...
- [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-> ...
- 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 ...
- [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 ...
- [LeetCode] Design Linked List 设计链表
Design your implementation of the linked list. You can choose to use the singly linked list or the d ...
随机推荐
- Java:对象的强、软、弱和虚引用的区别
1.对象的强.软.弱和虚引用 在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无法再使用这个对象.也就是说,只有对象处于可触及(reachable)状态,程序才能使用它.从JDK ...
- Chapter 3. Lexical Structure
/** * Expression = Expression1 [ExpressionRest] * ExpressionRest = [AssignmentOperator Expression1] ...
- 利用css实现搜索过滤
无意中找到一种利用css就可实现的搜索过滤的方法,不得不说看了代码之后确实被惊艳到了,亏我之前面试还因为做这个功能做太慢而拖了后腿.在此记录下代码: <!DOCTYPE html> < ...
- [PY3]——内置数据结构(1)——列表及其常用操作
列表及其常用操作_xmind图 about列表 列表是一个序列,用于顺序存储数据 列表分为两种:ArrayList(用数组实现).LinkedList(用链表实现) 定义与初始化 #l ...
- UEditor图片焦点错位,火狐document.body.scrollTop不管用的问题
转自 http://liyunpeng.iteye.com/blog/2068751 关于 document.body.scrollTop 在火狐浏览器中不管用的问题 看网上有人写通过判断docume ...
- WCF WCF的宿主
一.WCF服务应用程序与WCF服务库 我们在平时开发的过程中常用的项目类型有“WCF 服务应用程序”和“WCF服务库”. WCF服务应用程序,是一个可以执行的程序,它有独立的进程,WCF服务类契约的定 ...
- Docker学习之基本概念
Docker学习之基本概念 作为一个后端noder,不了解docker有点说不过去,这节开始,学习一些docker层面的东西. 什么是docker Docker最初是dotCloud公司创始人Solo ...
- 十、spark graphx的scala示例
简介 spark graphx官网:http://spark.apache.org/docs/latest/graphx-programming-guide.html#overview spark g ...
- php分页实例及其原理
Part1:实例 /** * 取得上次的过滤条件 * @param string $param_str 参数字符串,由list函数的参数组成 * @return 如果有,返回array('filter ...
- MySQL一查就会
Table1--mysql常用操作 主题 用例 说明 书写规范 数据库和表的名称不一定要大写. 输入文本类型的数据时都要加上单引号: NULL 表示未定义,它不会等于另一个NULL: 不要使用双引号. ...