21. 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.
解题思路:简单题,设置两个指针再链表上移动,每次将链表顶端的较小的元素取出接到新链表上即可。
代码如下:
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
ListNode *res(NULL);
ListNode *cur(NULL);
ListNode* l1Cur(l1), *l2Cur(l2);
res = new ListNode(-1);
cur = res;
while (l1Cur != NULL && l2Cur != NULL){
ListNode *tmp = new ListNode(-1);
tmp -> next = NULL;
tmp -> val = (l1Cur -> val < l2Cur -> val ? l1Cur -> val : l2Cur -> val);
ListNode *s1 = l1Cur;
l1Cur = (l1Cur -> val < l2Cur -> val ? l1Cur -> next : l1Cur);
l2Cur = (s1 -> val < l2Cur -> val ? l2Cur : l2Cur -> next);
cur -> next = tmp;
cur = cur -> next;
}
if(l1Cur != NULL){
cur -> next = l1Cur;
}
if(l2Cur != NULL){
cur -> next = l2Cur;
}
res = res -> next;
return res;
}
};
结果如下:
23. Merge k Sorted Lists
题目描述:Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
解题思路:解题思路同上题,只是一个简单的扩展而已。一个小技巧是当一个链表遍历完了就将它移除向量。
代码如下:
class Solution {
public:
ListNode* mergeKLists(vector<ListNode*>& lists) {
for(int i = 0; i < lists.size(); ++i){
if(lists[i] == NULL){
int j = lists.size() - 1;
while(lists[j] == NULL && j > i){
lists.pop_back();
--j;
}
if (lists[j] == NULL){
lists.pop_back();
} else{
lists[i] = lists[j];
lists.pop_back();
}
}
}
if(lists.size() == 0) return NULL;
ListNode *res = new ListNode(-1);
ListNode *curP = res;
while (lists.size() != 1){
ListNode *tmp = NULL;
int index = -1;
int min = 0;
for(int i = 0; i < lists.size(); ++i){
if(index == -1 || min > lists[i] -> val){
min = lists[i] -> val;
index = i;
}
}
tmp = new ListNode(-1);
tmp -> val = lists[index] -> val;
curP -> next = tmp;
curP = curP -> next;
lists[index] = lists[index] -> next;
if(lists[index] == NULL){
lists[index] = lists[lists.size() - 1];
lists.pop_back();
}
}
curP -> next = lists[0];
return res -> next;
}
};
结果如下:
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.
解题思路:设置前后两个相邻指针即可,需要注意的是指针是否已经达到了链表尾
代码如下:
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
ListNode *pre(NULL), *back(NULL), *left(head), *right(NULL);
if(left != NULL) right = left -> next;
while(left != NULL && right != NULL){
ListNode *preLNext(left -> next), * preRNext(right -> next);
right -> next = left;
left -> next = preRNext;
if(pre != NULL){
pre -> next = right;
} else {
head = right;
}
//move forward
pre = left;
left = left -> next;
if(left != NULL){
right = left -> next;
}
}
return head;
}
};
结果如下:
138. Copy List with Random Pointer
题目描述:
A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null.
Return a deep copy of the list.
解题思路:这一题是真正比较需要技巧的题目。
本人使用的技巧是:假设被复制的链表为L1, 生成的链表为L2。
将L1的每个节点的地址记录在数组当中;
将L1每个节点的next指向res中对应的节点,构成一个一一对应关系。
对于res中的每个节点,res -> randomP = L1 -> randomP -> next
最后根据数组将L1复原。
代码如下:
class Solution {
public:
RandomListNode *copyRandomList(RandomListNode *head) {
if(head == NULL) return NULL;
vector<RandomListNode*> precord;
RandomListNode *res(NULL), *recordH(head), *recordR;
res = new RandomListNode(-1);
recordR = res;
while(recordH != NULL){
precord.push_back(recordH);
RandomListNode *tmp = new RandomListNode(-1), *tmp1 = recordH;
tmp -> label = recordH -> label;
tmp -> random = recordH -> random;
recordH = recordH -> next;
recordR -> next = tmp;
recordR = recordR -> next;
tmp1 -> next = recordR;
}
recordR = res -> next;
while(recordR != NULL){
if(recordR -> random != NULL)
recordR -> random = recordR -> random -> next;
recordR = recordR -> next;
}
for(int i = 0; i < precord.size() - 1; ++i){
precord[i] -> next = precord[i + 1];
}
precord[precord.size() -1] -> next = NULL;
return res -> next;
}
};
结果如下: