Linked List
- Linked List
- Swap Nodes in Pairs
- Sort List
- Rotate List
- Reverse Nodes in k-Group
- Reverse Linked List
- Reverse Linked List II
- Reorder List
- Remove Nth Node From End of List
- Remove Linked List Elements
- Remove Duplicates from Sorted List
- Remove Duplicates from Sorted List II
- Partition List
- Palindrome Linked List
- Merge Two Sorted Lists
- Merge k Sorted Lists
- Linked List Cycle
- Linked List Cycle II
- Intersection of Two Linked Lists
- Insertion Sort List
- Delete Node in a Linked List
- Copy List with Random Pointer
- Convert Sorted List to Binary Search Tree
- Add Two Numbers
- 所有代码下载LeetCode-Linked List
- 所有内容目录CCPP Blog目录
24 Swap Nodes in Pairs
Given a linked list, swap every two adjacent nodes and return its head.
For example,
Given 1->2->3->4, you should return the list as 2->1->4->3.
Your algorithm should use only constant space. You may not modify the values in the list, only nodes itself can be changed.
分析:
题目要求:两个一组逆置相邻节点。
这是链表逆置的变种(升级)。但做法依然是那样:以前是逆置n个,现在是逆置两个,只不过需要逆置多次而已。注意细节,看图:逆置p1和p2,pPre和pNext分别指向前驱和后继。
参考:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* swapPairs(struct ListNode* head) {
//空链表和单一节点链表,不作处理
if(NULL == head || NULL == head->next) return head;
struct ListNode *p1, *p2, *pPre, *pNext;
p1 = head, p2 = head->next;
//第一对节点,做特殊处理
pNext = p2->next;
p2->next = p1;
p1->next = pNext;
pPre = p1;
head = p2; //这一句是特殊处理的理由
while(pNext)
{
p1 = pNext;
p2 = p1->next;
if(NULL == p2) break;
pNext = p2->next;
//以下两句代码:逆置相邻节点
p2->next = p1;
p1->next = pNext;
pPre->next = p2;
pPre = p1;
}
return head;
}
148 Sort List
Sort a linked list in O(n log n) time using constant space complexity.
分析:
题目要求:对单链表排序,时间复杂度是O(n log n),空间复杂度是O(1)。
我们可以先把元素取出,排序好后,再放回去,这是参考1中的做法。时间复杂度满足,空间复杂度不满足。
另外,借助归并排序的思想,我们有了参考2。需要注意的是,如何使用快慢指针找到链表的中间节点?这需要多加体会。
参考1:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
#include <algorithm>
class Solution {
public:
ListNode* sortList(ListNode* head) {
if(NULL == head || NULL == head->next){
return head;
}
vector<int> vec;
ListNode *p = head;
while(p){
vec.push_back(p->val);
p = p->next;
}
sort(vec.begin(), vec.end()); //n*logn
p = head;
int i = 0;
while(p){
p->val = vec[i];
i++;
p = p->next;
}
return head;
}
};
参考2:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* merge(struct ListNode *head1, struct ListNode *head2)
{
if(NULL == head1) return head2;
if(NULL == head2) return head1;
struct ListNode *head = (struct ListNode*)malloc(sizeof(struct ListNode));
struct ListNode *p = head;
p->next = NULL;
while(head1 && head2)
{
if(head1->val < head2->val)
{
p->next = head1;
head1 = head1->next;
}
else
{
p->next = head2;
head2 = head2->next;
}
p = p->next;
}
if(head1)
{
p->next = head1;
}
if(head2)
{
p->next = head2;
}
struct ListNode *temp = head;
head = head->next;
free(temp); //释放头节点
return head;
}
struct ListNode* mergeSort(struct ListNode *head)
{
if(NULL == head || NULL == head->next) return head;
//使用快慢指针,寻找中间节点,从而链表一分为二
struct ListNode *slow, *fast, *p;
slow = fast = head;
while(fast)
{
fast = fast->next;
if(fast)
{
fast = fast->next;
if(NULL == fast) break;
}
else break;
slow = slow->next;
}
//此时slow即是中间节点
p = slow->next;
slow->next = NULL;
struct ListNode *pLeft = mergeSort(head);
struct ListNode *pRight = mergeSort(p);
return merge(pLeft, pRight);
}
struct ListNode* sortList(struct ListNode* head) {
if(NULL == head || NULL == head->next) return head;
return mergeSort(head);
}
61 Rotate List
Given a list, rotate the list to the right by k places, where k is non-negative.
For example:
Given 1->2->3->4->5->NULL and k = 2,
return 4->5->1->2->3->NULL.
分析:
这是链表逆置的变种,把握基本操作,其它的就没什么好说的了。
参考:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* rotateRight(struct ListNode* head, int k) {
if(NULL == head || NULL == head->next || 0 == k) return head;
struct ListNode *p, *pEnd;
p = pEnd = head;
int n = 1;
while(pEnd->next)
{
pEnd = pEnd->next;
n++;
}
k %= n; //规范k值
k = n - k;
k--;
while(k)
{
p = p->next;
k--;
}
pEnd->next = head;
head = p->next;
p->next = NULL;
return head;
}
25 Reverse Nodes in k-Group
Given a linked list, reverse the nodes of a linked list k at a time and return its modified list.
If the number of nodes is not a multiple of k then left-out nodes in the end should remain as it is.
You may not alter the values in the nodes, only nodes itself may be changed.
Only constant memory is allowed.
For example,
Given this linked list: 1->2->3->4->5
For k = 2, you should return: 2->1->4->3->5
For k = 3, you should return: 3->2->1->4->5
分析:
这是24 Swap Nodes in Pairs的升级,如果不会,就先弄懂24题。
参考:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* reverseKGroup(struct ListNode* head, int k) {
if(NULL == head || NULL == head->next || k < 2) return head;
int i, n;
n = 0;
struct ListNode *p = head;
while(p){
n++;
p = p->next;
}
struct ListNode *pPre, *pCur, *pNext;
struct ListNode *pStart, *pEnd;
pStart = head;
if(n >= k){
pPre = pStart, pCur = pStart->next;
i = 1;
while(i < k){
pNext = pCur->next;
pCur->next = pPre;
pPre = pCur;
pCur = pNext;
i++;
}
pEnd = pStart;
pEnd->next = p