[算法专题] LinkedList
前段时间在看一本01年出的旧书《effective Tcp/Ip programming》,这个算法专题中断了几天,现在继续写下去。
Introduction
对于单向链表(singly linked list),每个节点有⼀个next指针指向后一个节点,还有一个成员变量用以储存数值;对于双向链表(Doubly LinkedList),还有一个prev指针指向前一个节点。与数组类似,搜索链表需要O(n)的时间复杂度,但是链表不能通过常数时间读取第k个数据。链表的优势在于能够以较⾼的效率在任意位置插⼊或删除一个节点。
Dummy Node,Scenario: When the head is not determinated
之前在博客中有几篇文章,已经介绍了Dummy Node的使用,实际上Dummy Node就是所谓的头结点,使用Dummy Node可以简化操作,统一处理head与其他node的操作。
链表操作时利⽤用dummy node是⼀一个⾮非常好⽤用的trick:只要涉及操作head节点,不妨创建dummy node:
ListNode *dummy = new ListNode(0);
dummy->next = head;
废话少说,来看以下几道题:
1. Remove Duplicates from Sorted List I, II
2. Merge Two Sorted Lists
3. Partition List
4. Reverse Linked List I,II
1. Remove Duplicates from Sorted List I
https://leetcode.com/problems/remove-duplicates-from-sorted-list/
Given a sorted linked list, delete all duplicates such that each element appear only once.
For example,
Given1->1->2
, return1->2
.Given
1->1->2->3->3
, return1->2->3
.
这题我们的策略遇到重复的node,保留第一个,删除后面的,因此并不会改动head节点,所以下面的代码没有设置dummy node。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* deleteDuplicates(ListNode* head) {
if (head == NULL) {
return head;
} ListNode *headBak = head;
while (head->next) {
if (head->val == head->next->val) {
// 保留第一个,删除后面的
ListNode *tmp = head->next;
head->next = tmp->next;
delete tmp;
} else {
head = head->next;
}
} return headBak;
}
};
2. Remove Duplicates from Sorted List II
https://leetcode.com/problems/remove-duplicates-from-sorted-list-ii/
Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list.
For example,
Given1->2->3->3->4->4->5
, return1->2->5
.Given
1->1->1->2->3
, return2->3
.
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* deleteDuplicates(ListNode* head) {
if (head == NULL) {
return head;
} ListNode *dummy = new ListNode(0);
dummy->next = head; ListNode *pos = dummy; // 至少需要head 和 head->next 才可能有重复
while (pos->next && pos->next->next) {
if (pos->next->val == pos->next->next->val) {
int preVal = pos->next->val;
// 至少保证有两个node,才会有重复
while (pos->next && pos->next->val == preVal) {
ListNode *tmp = pos->next;
pos->next = tmp->next;
delete tmp;
}
} else {
pos = pos->next;
}
} return dummy->next;
}
};
3. Merge Two Sorted Lists
https://leetcode.com/problems/merge-two-sorted-lists/
Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists.
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
ListNode *dummy = new ListNode(0);
ListNode *curr = dummy; while (l1 && l2) {
if (l1->val < l2->val) {
curr->next = l1;
l1 = l1->next;
} else {
curr->next = l2;
l2 = l2->next;
} curr = curr->next;
} if (l1) {
curr->next = l1;
} if (l2) {
curr->next = l2;
} return dummy->next;
}
};
4. Partition List
https://leetcode.com/problems/partition-list/
Given a linked list and a value x, partition it such that all nodes less than x come before nodes greater than or equal to x.
You should preserve the original relative order of the nodes in each of the two partitions.
For example,
Given1->4->3->2->5->2
and x = 3,return
1->2->2->4->3->5
.
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* partition(ListNode* head, int x) {
if (head == NULL) {
return NULL;
} ListNode *leftDummy = new ListNode(0);
ListNode *left = leftDummy; ListNode *rightDummy = new ListNode(0);
ListNode *right = rightDummy; ListNode *curr = head; while (curr) {
if (curr->val < x) {
left->next = curr;
left = left->next;
curr = curr->next;
} else {
right->next = curr;
right = right->next;
curr = curr->next;
}
} left->next = rightDummy->next;
right->next = NULL; return leftDummy->next;
}
};
Basic Skills
5. Reverse Linked List
https://leetcode.com/problems/reverse-linked-list/
Reverse a singly linked list.
Hint:
A linked list can be reversed either iteratively or recursively. Could you implement both?
非递归写法如下:
/**
* 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 == NULL) {
return NULL;
} ListNode *pre = NULL;
ListNode *curr = head;
ListNode *next = NULL;
while (curr) {
next = curr->next; curr->next = pre;
pre = curr; curr = next;
} 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) {
// empty list
if (head == NULL) return head;
// Base case
if (head->next == NULL) return head; // reverse from the rest after head
ListNode *newHead = reverseList(head->next);
// reverse between head and head->next
head->next->next = head;
// unlink list from the rest
head->next = NULL; return newHead;
}
};
6. Reverse Linked List II
https://leetcode.com/problems/reverse-linked-list-ii/
Reverse a linked list from position m to n. Do it in-place and in one-pass.
For example:
Given1->2->3->4->5->NULL
, m = 2 and n = 4,return
1->4->3->2->5->NULL
.Note:
Given m, n satisfy the following condition:
1 ≤ m ≤ n ≤ length of list.
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseBetween(ListNode* head, int m, int n) {
if (head == NULL) {
return NULL;
} ListNode *dummy = new ListNode(0);
dummy->next = head;
ListNode *pos = dummy; for (int i = 0; i <= m - 2; i++) {
pos = pos->next;
}
ListNode *mPreNode = pos;
ListNode *mCurrNode = pos->next; ListNode *nPreNode = NULL;
ListNode *nCurrNode = mCurrNode;
ListNode *nNextNode = NULL;
for (int i = m; i <= n; i++) {
nNextNode = nCurrNode->next; nCurrNode->next = nPreNode;
nPreNode = nCurrNode; nCurrNode = nNextNode;
} mPreNode->next = nPreNode;
mCurrNode->next = nCurrNode; return dummy->next;
}
};
7. Remove Linked List Elements
https://leetcode.com/problems/remove-linked-list-elements/
Remove all elements from a linked list of integers that have value val.
Example
Given: 1 --> 2 --> 6 --> 3 --> 4 --> 5 --> 6, val = 6
Return: 1 --> 2 --> 3 --> 4 –> 5
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
ListNode *dummy = new ListNode(0);
dummy->next = head; ListNode *pre = dummy;
ListNode *curr = head;
while (curr) {
if (curr->val == val) {
ListNode *waitForDel = curr; pre->next = curr->next;
curr = curr->next; delete waitForDel;
} else {
pre = pre->next;
curr = curr->next;
}
} return dummy->next;
}
};
8. Remove Nth Node From End of List
https://leetcode.com/problems/remove-nth-node-from-end-of-list/
Given a linked list, remove the nth node from the end of list and return its head.
For example,
Given linked list: 1->2->3->4->5, and n = 2. After removing the second node from the end, the linked list becomes 1->2->3->5.Note:
Given n will always be valid.
Try to do this in one pass.
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode *dummy = new ListNode(0);
dummy->next = head; ListNode *slow = dummy;
ListNode *fast = dummy;
for (int i = 0; i < n - 1; i++) {
fast = fast->next;
} ListNode *pre = NULL;
while (fast->next) {
pre = slow;
slow = slow->next;
fast = fast->next;
} pre->next = slow->next;
delete slow; return dummy->next;
}
};
9. Remove Duplicates from Sorted List
https://leetcode.com/problems/remove-duplicates-from-sorted-list/
Given a sorted linked list, delete all duplicates such that each element appear only once.
For example,
Given1->1->2
, return1->2
.Given
1->1->2->3->3
, return1->2->3
.
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* deleteDuplicates(ListNode* head) {
ListNode *pos = head;
while (pos) {
if (pos->next && pos->val == pos->next->val) {
ListNode *waitForDel = pos->next;
pos->next = pos->next->next;
delete waitForDel;
} else {
pos = pos->next;
}
} return head;
}
}; /**
*
class Solution {
public:
ListNode *deleteDuplicates(ListNode *head) {
if (head == NULL) {
return NULL;
} ListNode *node = head;
while (node->next != NULL) {
if (node->val == node->next->val) {
ListNode *temp = node->next;
node->next = node->next->next;
delete temp;
} else {
node = node->next;
}
} return head;
}
};
*
*/
10. Remove Duplicates from Sorted List II
https://leetcode.com/problems/remove-duplicates-from-sorted-list-ii/
Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list.
For example,
Given1->2->3->3->4->4->5
, return1->2->5
.Given
1->1->1->2->3
, return2->3
.
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* deleteDuplicates(ListNode* head) {
if (head == NULL) {
return head;
} ListNode *dummy = new ListNode(0);
dummy->next = head; ListNode *pos = dummy; // 至少需要head 和 head->next 才可能有重复
while (pos->next && pos->next->next) {
if (pos->next->val == pos->next->next->val) {
int preVal = pos->next->val;
// 至少保证有两个node,才会有重复
while (pos->next && pos->next->val == preVal) {
ListNode *tmp = pos->next;
pos->next = tmp->next;
delete tmp;
}
} else {
pos = pos->next;
}
} return dummy->next;
}
};
(待续)
8
8
8
[算法专题] LinkedList的更多相关文章
- 【枚举Day1】20170529-2枚举算法专题练习 题目
20170529-2枚举算法专题练习 题解: http://www.cnblogs.com/ljc20020730/p/6918360.html 青岛二中日期 序号 题目名称 输入文件名 输出文件名 ...
- NOIp 图论算法专题总结 (1):最短路、最小生成树、最近公共祖先
系列索引: NOIp 图论算法专题总结 (1) NOIp 图论算法专题总结 (2) NOIp 图论算法专题总结 (3) 最短路 Floyd 基本思路:枚举所有点与点的中点,如果从中点走最短,更新两点间 ...
- NOIp 图论算法专题总结 (2)
系列索引: NOIp 图论算法专题总结 (1) NOIp 图论算法专题总结 (2) NOIp 图论算法专题总结 (3) 树链剖分 https://oi-wiki.org/graph/heavy-lig ...
- NOIp 图论算法专题总结 (3):网络流 & 二分图 简明讲义
系列索引: NOIp 图论算法专题总结 (1) NOIp 图论算法专题总结 (2) NOIp 图论算法专题总结 (3) 网络流 概念 1 容量网络(capacity network)是一个有向图,图的 ...
- ACM&OI 基础数论算法专题
ACM&OI 基础数学算法专题 一.数论基础 质数及其判法 (已完结) 质数的两种筛法 (已完结) 算数基本定理与质因数分解 (已完结) 约数与整除 (已完结) 整除分块 (已完结) 最大公约 ...
- 每周一练 之 数据结构与算法(LinkedList)
这是第三周的练习题,原本应该先发第二周的,因为周末的时候,我的母亲大人来看望她的宝贝儿子,哈哈,我得带她看看厦门这座美丽的城市呀. 这两天我抓紧整理下第二周的题目和答案,下面我把之前的也列出来: 1. ...
- $vjudge-$基本算法专题题解
考完期末又双叒回来刷普及题辣$kk$ 然后放个链接趴还是$QwQ$ [X]$A$ 因为是嘤文($bushi$所以放个题意趴$QwQ$ 就汉诺塔问题,只是说有四个塔$A,B,C,D$,要求输出有1-12 ...
- ACM&OI 基础数学算法专题
[前言] 本人学习了一定时间的算法,主要精力都花在数学类的算法上面 而数学类的算法中,本人的大部分精力也花费在了数论算法上 此类算法相对抽象,证明过程比较复杂 网络上的博客有写得非常好的,但也有写得不 ...
- 算法专题 | 10行代码实现的最短路算法——Bellman-ford与SPFA
今天是算法数据结构专题的第33篇文章,我们一起来聊聊最短路问题. 最短路问题也属于图论算法之一,解决的是在一张有向图当中点与点之间的最短距离问题.最短路算法有很多,比较常用的有bellman-ford ...
随机推荐
- IntelliJ IDEA 中创建maven项目
IDEA作为最好得开发工具之一集成了maven工具,今天记录一下我创建使用idea创建maven项目 1.双击IDEA图标,进入到如下界面,在该页面中,点击箭头所示的“Create New Proje ...
- idea搭spring boot项目
Spring Boot是由Pivotal团队提供的全新框架,设计目的是用来简化新Spring应用的初始搭建以及开发过程.它主要推崇的是'消灭配置’,实现零配置. 那么,如何在idea中创建一个spri ...
- 制造业期刊-ZT
小虫一名英国博后,前阵发书,认识了很多机械制造领域的伙伴.得知我录用了多篇顶刊后,很多人私聊我求经验. 哎,哪里那么容易.回想过去5年,制造领域的期刊基本都被拒过一圈.当年自己投稿时就发现,制造顶刊的 ...
- JVM系列3:类加载机制
了解类加载机制也是深入了解Java的重要一环,它包括加载过程.类加载器.加载机制等内容. 以下是我总结的思维导图. 首先讲讲类加载的时机,以下是会触发类加载的时机: 1.new.get/put/inv ...
- javascript中的类型检测
最常见的是使用 typeof 来判断数据类型 可以区分4种基本类型,即 “number”,”string”,”undefined”,”boolean”,第5种基本类型null类型返回值为object( ...
- DB2(Procedure)存储过程遍历循环!
有时候一些复杂的业务逻辑将要通过存储过程的循环语句进行处理;以下列出2种DB2存储过程的循环语句,方便以后的查看并使用! 推荐第一种方式的使用,最大的优点就是比较直观;在需要操作很多字段的情况下,不需 ...
- java虚拟机--->>程序计数器
程序计数器是一块较小的内存空间,他可以看做是当前线程所执行的行号指示器.在虚拟机的概念模型(仅是概念模型,各种虚拟机可能会通过一些更高效率的方式去实现)里,字节码解释器工作室就是通过改变这个计数器的值 ...
- java简单的文件读写工具类
import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.BufferedRead ...
- php json 写入 mysql 的例子
$a['aaa']='aaaa'; $a['bbb']='bbb'; $a['ccc']='ccc'; $arr['step_name']='kfkf'; $arr['process_name']=' ...
- java爬虫框架webmagic学习(一)
1. 爬虫的分类:分布式和单机 分布式主要就是apache的nutch框架,java实现,依赖hadoop运行,学习难度高,一般只用来做搜索引擎开发. java单机的框架有:webmagic和webc ...