本文主要分类总结剑指offer以及其对应的leetcode相关题目。
链表
复杂链表的复制
对应leetcode 138.复制带随机指针的链表
题目描述:
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.
第一种解法主要利用了哈希表:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/*
// Definition for a Node.
class Node {
public:
int val;
Node* next;
Node* random;
Node() {}
Node(int _val, Node* _next, Node* _random) {
val = _val;
next = _next;
random = _random;
}
};
*/
class Solution {
public:
Node* copyRandomList(Node* head) {
if(!head)
return nullptr;
if(mp.find(head)==mp.end()){
mp[head] = new Node(head->val);
mp[head]->next = copyRandomList(head->next);
mp[head]->random = copyRandomList(head->random);
}
return mp[head];
}
};
private:
unordered_map<Node*,Node*> mp;
第二种解法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
/*
struct RandomListNode {
int label;
struct RandomListNode *next, *random;
RandomListNode(int x) :
label(x), next(NULL), random(NULL) {
}
};
*/
class Solution {
public:
RandomListNode* Clone(RandomListNode* pHead)
{
CloneNodes(pHead);
ConnectSiblingNodes(pHead);
return ReconnectNodes(pHead);
}
//第一步,复制复杂指针的label和next
void CloneNodes(RandomListNode* pHead){
RandomListNode* pNode = pHead;
while(pNode != NULL){
RandomListNode* pCloned = new RandomListNode(0);
pCloned->label = pNode->label;
pCloned->next = pNode->next;
pCloned->random = NULL;
pNode->next = pCloned;
pNode = pCloned->next;
}
}
//第二步,处理复杂指针的random
void ConnectSiblingNodes(RandomListNode* pHead){
RandomListNode* pNode = pHead;
while(pNode != NULL){
RandomListNode* pCloned = pNode->next;
if(pNode->random != NULL){
pCloned->random = pNode->random->next;
}
pNode = pCloned->next;
}
}
//第三步,拆分复杂指针
RandomListNode* ReconnectNodes(RandomListNode* pHead){
RandomListNode* pNode = pHead;
RandomListNode* pClonedHead = NULL;
RandomListNode* pClonedNode = NULL;
if(pNode != NULL){
pClonedHead = pClonedNode = pNode->next;
pNode->next = pClonedNode->next;
pNode = pNode->next;
}
while(pNode != NULL){
pClonedNode->next = pNode->next;
pClonedNode = pClonedNode->next;
pNode->next = pClonedNode->next;
pNode = pNode->next;
}
return pClonedHead;
}
};
两个链表的第一个公共结点
题目描述:
输入两个链表,找出它们的第一个公共结点。
解法一:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
if(pHead1 == NULL || pHead2 == NULL)
return NULL;
stack<ListNode*> s1,s2;
while(pHead1!=NULL){
s1.push(pHead1);
pHead1 = pHead1->next;
}
while(pHead2!=NULL){
s2.push(pHead2);
pHead2 = pHead2->next;
}
ListNode *res = NULL;
while(!s1.empty()&&!s2.empty()){
if(s1.top()==s2.top())
res = s1.top();
s1.pop();
s2.pop();
}
return res;
}
};
解法二:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
if(pHead1 == NULL || pHead2 == NULL)
return NULL;
unsigned int l1 = getLength(pHead1);
unsigned int l2 = getLength(pHead2);
ListNode* plong = pHead1;
ListNode* pshort = pHead2;
int gap = l1-l2;
if(l1 < l2){
plong = pHead2;
pshort = pHead1;
gap = l2-l1;
}
for(int i = 0; i < gap; i++){
plong = plong->next;
}
while(plong!=NULL && pshort !=NULL&& plong!=pshort){
plong = plong->next;
pshort = pshort->next;
}
return plong;
}
unsigned int getLength(ListNode* pHead){
if(pHead == NULL)
return 0;
unsigned int res = 0;
while(pHead!=NULL){
pHead = pHead->next;
res++;
}
return res;
}
};