Skip to content

Commit d8fcbf1

Browse files
authored
Update README.md
1 parent d29d290 commit d8fcbf1

File tree

1 file changed

+155
-132
lines changed
  • cpp/Intersection-Of-Two-Linked-Lists

1 file changed

+155
-132
lines changed

Diff for: cpp/Intersection-Of-Two-Linked-Lists/README.md

+155-132
Original file line numberDiff line numberDiff line change
@@ -1,195 +1,218 @@
1-
# 题目描述: 两数之和 II - 输入有序数组
1+
# 题目描述: 相交链表
22

3-
给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数
3+
编写一个程序,找到两个单链表相交的起始节点
44

5-
函数应该返回这两个下标值 index1 和 index2,其中 index1 必须小于 index2。
6-
7-
**说明:**
8-
- 返回的下标值(index1 和 index2)不是从零开始的。
9-
- 你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素。
5+
如下面的两个链表:
6+
![](https://assets.leetcode-cn.com/aliyun-lc-upload/uploads/2018/12/14/160_statement.png)
7+
在节点 c1 开始相交。
108

9+
![](https://assets.leetcode-cn.com/aliyun-lc-upload/uploads/2018/12/14/160_example_1.png)
1110

1211
**示例 1:**
1312
```
14-
输入: numbers = [2, 7, 11, 15], target = 9
15-
输出: [1,2]
16-
解释: 2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。
13+
输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3
14+
输出:Reference of the node with value = 8
15+
输入解释:相交节点的值为 8 (注意,如果两个列表相交则不能为 0)。从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,0,1,8,4,5]。在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点
1716
```
1817

18+
![](https://assets.leetcode-cn.com/aliyun-lc-upload/uploads/2018/12/14/160_example_2.png)
19+
20+
**示例 2:**
21+
```
22+
输入:intersectVal = 2, listA = [0,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1
23+
输出:Reference of the node with value = 2
24+
输入解释:相交节点的值为 2 (注意,如果两个列表相交则不能为 0)。从各自的表头开始算起,链表 A 为 [0,9,1,2,4],链表 B 为 [3,2,4]。在 A 中,相交节点前有 3 个节点;在 B 中,相交节点前有 1 个节点。
25+
```
26+
27+
![](https://assets.leetcode-cn.com/aliyun-lc-upload/uploads/2018/12/14/160_example_3.png)
28+
29+
**示例 3:**
30+
```
31+
输入:intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2
32+
输出:null
33+
输入解释:从各自的表头开始算起,链表 A 为 [2,6,4],链表 B 为 [1,5]。由于这两个链表不相交,所以 intersectVal 必须为 0,而 skipA 和 skipB 可以是任意值。
34+
解释:这两个链表不相交,因此返回 null。
35+
```
36+
37+
1938
# 解题思路:
20-
此题与剑指offer第57题题目一类似
39+
此题与剑指offer第52题题目一类似
2140

2241
方法一:暴力遍历
2342

24-
方法二:哈希表
25-
26-
方法三:双指针
43+
方法二:找出2个链表的长度,然后让长的先走两个链表的长度差,然后再一起走(因为2个链表用公共的尾部)。如果存在共同节点的话,那么从该节点,两个链表之后的元素都是相同的。 也就是说两个链表从尾部往前到某个点,节点都是一样的。
2744

2845

2946
# 时间复杂度:
30-
方法一:O(n<sup>2)
31-
32-
方法二:O(n)
47+
方法一:O(nm)
3348

34-
方法三:O(n)
49+
方法二:O(n+m)
3550
# 空间复杂度
3651
方法一:O(1)
3752

38-
方法二:O(n)
53+
方法二:O(1)
3954

40-
方法三:O(1)
4155

4256
# 代码
4357

4458
## [C++](./Intersection-Of-Two-Linked-Lists.cpp):
4559

46-
### 方法一: 暴力法
60+
### 方法一: 暴力遍历法
4761
```c++
62+
/**
63+
* Definition for singly-linked list.
64+
* struct ListNode {
65+
* int val;
66+
* ListNode *next;
67+
* ListNode(int x) : val(x), next(NULL) {}
68+
* };
69+
*/
4870
class Solution {
4971
public:
50-
vector<int> twoSum(vector<int>& numbers, int target) {
51-
vector <int> res (2,0);
52-
if (numbers.empty())
53-
return res;
54-
int n = numbers.size();
55-
for (int i=0;i<n;i++)
72+
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
73+
if (headA==NULL || headB == NULL) return NULL;
74+
ListNode* p = headA;
75+
ListNode* q = headB;
76+
while(p)
5677
{
57-
for (int j = i+1; j<n;j++)
78+
q = headB;
79+
while(q)
5880
{
59-
if (numbers[i]+numbers[j]==target)
81+
if (p->val==q->val)
6082
{
61-
res[0] = numbers[i];
62-
res[1] = numbers[j];
63-
break;
83+
return p;
84+
}
85+
else
86+
{
87+
q = q->next;
6488
}
6589
}
90+
p = p->next;
6691
}
67-
return res;
92+
return NULL;
6893
}
6994
};
7095
```
7196
72-
### 方法二: 哈希表
97+
### 方法二:
7398
```c++
99+
/**
100+
* Definition for singly-linked list.
101+
* struct ListNode {
102+
* int val;
103+
* ListNode *next;
104+
* ListNode(int x) : val(x), next(NULL) {}
105+
* };
106+
*/
74107
class Solution {
75108
public:
76-
vector<int> twoSum(vector<int>& numbers, int target) {
77-
vector <int> res (2,0);
78-
if (numbers.empty())
79-
return res;
80-
int n = numbers.size();
81-
unordered_map<int,int> record;
82-
for (int i=0;i<n;i++)
109+
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
110+
if (headA==NULL || headB==NULL) return NULL;
111+
ListNode* p = headA;
112+
ListNode* q = headB;
113+
int n=0,m=0;
114+
while(p)
83115
{
84-
int complement = target -numbers[i];
85-
if (record.find(complement)!=record.end())
86-
{
87-
res[0] = complement;
88-
res[1] = nums[i];
89-
break;
90-
}
91-
record[numbers[i]] = i;
116+
n++;
117+
p=p->next;
92118
}
93-
return res;
94-
}
95-
};
96-
```
97-
98-
### 方法三:双指针
99-
```c++
100-
class Solution {
101-
public:
102-
vector<int> twoSum(vector<int>& nums, int target) {
103-
vector <int> res (2,0);
104-
if (nums.empty())
105-
return res;
106-
int n = nums.size();
107-
int left = 0;
108-
int right = n-1;
109-
while (right>left)
119+
while(q)
110120
{
111-
if (nums[left]+nums[right]==target)
112-
{
113-
res[0] = nums[left];
114-
res[1] = nums[right];
115-
break;
116-
}
117-
if (nums[left]+nums[right]>target)
118-
{
119-
right--;
120-
}
121-
if (nums[left]+nums[right]<target)
122-
{
123-
left++;
124-
}
121+
m++;
122+
q=q->next;
125123
}
124+
p = headA;
125+
q = headB;
126+
int k = 0;
127+
if (n>=m)
128+
{
129+
k=n-m;
130+
}
131+
else
132+
{
133+
k=m-n;
134+
p=headB;
135+
q=headA;
136+
}
137+
for (int i=0;i<k;i++)
138+
{
139+
p = p->next;
140+
}
141+
while(p && q && p!=q)
142+
{
143+
p = p->next;
144+
q = q->next;
145+
}
146+
ListNode* res = p;
126147
return res;
127148
}
128149
};
129150
```
130-
131-
132151
## [Python:](https://github.com/bryceustc/LeetCode_Note/blob/master/python/Intersection-Of-Two-Linked-Lists/Intersection-Of-Two-Linked-Lists.py)
133-
### 方法一:暴力法
152+
### 方法一:暴力遍历法
134153
```python
154+
# -*- coding:utf-8 -*-
155+
# class ListNode:
156+
# def __init__(self, x):
157+
# self.val = x
158+
# self.next = None
135159
class Solution:
136-
def twoSum(self, nums, target):
160+
def FindFirstCommonNode(self, l1, l2):
137161
# write code here
138-
res = []
139-
n = len(nums)
140-
if n==0:
141-
return res
142-
for i in range(n):
143-
for j in range(i+1,n):
144-
if nums[i]+nums[j]==target:
145-
res.append(nums[i])
146-
res.append(nums[j])
147-
return res
148-
return res
162+
if l1==None or l2 == None:
163+
return None
164+
p = l1
165+
q = l2
166+
while p:
167+
q = l2
168+
while q:
169+
if p.val==q.val:
170+
return p
171+
else:
172+
q = q.next
173+
p = p.next
174+
return None
149175
```
150-
### 方法二 :哈希表
176+
### 方法二 :
151177
```python
152-
class Solution:
153-
def twoSum(self, nums, target):
154-
# write code here
155-
res = []
156-
record = {}
157-
n = len(nums)
158-
if n==0:
159-
return res
160-
for index,num in enumerate (nums):
161-
complement = target - num
162-
if complement in record:
163-
res.append(complement)
164-
res.append(num)
165-
return res
166-
record[num] = index
167-
return res
168-
```
178+
# Definition for singly-linked list.
179+
# class ListNode:
180+
# def __init__(self, x):
181+
# self.val = x
182+
# self.next = None
169183

170-
### 方法三 : 双指针
171-
```python
172184
class Solution:
173-
def twoSum(self, nums, target):
174-
# write code here
175-
res = []
176-
n = len(nums)
177-
left = 0
178-
right = n-1
179-
while right>left:
180-
if nums[left]+nums[right]==target:
181-
res.append(nums[left])
182-
res.append(nums[right])
183-
return res
184-
if nums[left]+nums[right]>target:
185-
right-=1
186-
else:
187-
left+=1
185+
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
186+
if headA==None or headB == None:
187+
return None
188+
p = headA
189+
q = headB
190+
n =0
191+
m=0
192+
while p:
193+
n+=1
194+
p = p.next
195+
while q:
196+
m+=1
197+
q = q.next
198+
p = headA
199+
q = headB
200+
k = 0
201+
if n>=m:
202+
k = n-m
203+
else:
204+
p = headB
205+
q = headA
206+
k = m-n
207+
for i in range(k):
208+
p = p.next
209+
while p and q and p!=q:
210+
p = p.next
211+
q = q.next
212+
res = p
188213
return res
189214
```
190215

191-
192-
193216
# 参考
194217
- [剑指offer第52题-两个链表的第一个公共节点](https://github.com/bryceustc/CodingInterviews/blob/master/FirstCommonNodesInLists/README.md)
195218

0 commit comments

Comments
 (0)