Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 6705995

Browse files
authored
Merge branch 'youngyangyang04:master' into master
2 parents b124152 + 5cbb991 commit 6705995

File tree

95 files changed

+3508
-1913
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

95 files changed

+3508
-1913
lines changed

‎.DS_Store‎

-6 KB
Binary file not shown.

‎.gitignore‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
**/.DS_Store

‎problems/0001.两数之和.md‎

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141

4242
那么我们就应该想到使用哈希法了。
4343

44-
因为本地,我们不仅要知道元素有没有遍历过,还有知道这个元素对应的下标,**需要使用 key value结构来存放,key来存元素,value来存下标,那么使用map正合适**
44+
因为本地,我们不仅要知道元素有没有遍历过,还要知道这个元素对应的下标,**需要使用 key value结构来存放,key来存元素,value来存下标,那么使用map正合适**
4545

4646
再来看一下使用数组和set来做哈希法的局限。
4747

@@ -151,7 +151,7 @@ public int[] twoSum(int[] nums, int target) {
151151
```
152152

153153
Python:
154-
154+
(版本一) 使用字典
155155
```python
156156
class Solution:
157157
def twoSum(self, nums: List[int], target: int) -> List[int]:
@@ -163,6 +163,53 @@ class Solution:
163163
records[value] = index # 遍历当前元素,并在map中寻找是否有匹配的key
164164
return []
165165
```
166+
(版本二)使用集合
167+
```python
168+
class Solution:
169+
def twoSum(self, nums: List[int], target: int) -> List[int]:
170+
#创建一个集合来存储我们目前看到的数字
171+
seen = set()
172+
for i, num in enumerate(nums):
173+
complement = target - num
174+
if complement in seen:
175+
return [nums.index(complement), i]
176+
seen.add(num)
177+
```
178+
(版本三)使用双指针
179+
```python
180+
class Solution:
181+
def twoSum(self, nums: List[int], target: int) -> List[int]:
182+
# 对输入列表进行排序
183+
nums_sorted = sorted(nums)
184+
185+
# 使用双指针
186+
left = 0
187+
right = len(nums_sorted) - 1
188+
while left < right:
189+
current_sum = nums_sorted[left] + nums_sorted[right]
190+
if current_sum == target:
191+
# 如果和等于目标数,则返回两个数的下标
192+
left_index = nums.index(nums_sorted[left])
193+
right_index = nums.index(nums_sorted[right])
194+
if left_index == right_index:
195+
right_index = nums[left_index+1:].index(nums_sorted[right]) + left_index + 1
196+
return [left_index, right_index]
197+
elif current_sum < target:
198+
# 如果总和小于目标,则将左侧指针向右移动
199+
left += 1
200+
else:
201+
# 如果总和大于目标值,则将右指针向左移动
202+
right -= 1
203+
```
204+
(版本四)暴力法
205+
```python
206+
class Solution:
207+
def twoSum(self, nums: List[int], target: int) -> List[int]:
208+
for i in range(len(nums)):
209+
for j in range(i+1, len(nums)):
210+
if nums[i] + nums[j] == target:
211+
return [i,j]
212+
```
166213

167214
Go:
168215

‎problems/0015.三数之和.md‎

Lines changed: 53 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -298,61 +298,72 @@ class Solution {
298298
```
299299

300300
Python:
301+
(版本一) 双指针
301302
```Python
302303
class Solution:
303-
def threeSum(self, nums):
304-
ans = []
305-
n = len(nums)
304+
def threeSum(self, nums: List[int]) -> List[List[int]]:
305+
result = []
306306
nums.sort()
307-
# 找出a + b + c = 0
308-
# a = nums[i], b = nums[left], c = nums[right]
309-
for i in range(n):
310-
left = i + 1
311-
right = n - 1
312-
# 排序之后如果第一个元素已经大于零,那么无论如何组合都不可能凑成三元组,直接返回结果就可以了
313-
if nums[i] > 0:
314-
break
315-
if i >= 1 and nums[i] == nums[i - 1]: # 去重a
307+
308+
for i in range(len(nums)):
309+
# 如果第一个元素已经大于0,不需要进一步检查
310+
if nums[i] > 0:
311+
return result
312+
313+
# 跳过相同的元素以避免重复
314+
if i > 0 and nums[i] == nums[i - 1]:
316315
continue
317-
while left < right:
318-
total = nums[i] + nums[left] + nums[right]
319-
if total > 0:
320-
right -= 1
321-
elif total < 0:
316+
317+
left = i + 1
318+
right = len(nums) - 1
319+
320+
while right > left:
321+
sum_ = nums[i] + nums[left] + nums[right]
322+
323+
if sum_ < 0:
322324
left += 1
325+
elif sum_ > 0:
326+
right -= 1
323327
else:
324-
ans.append([nums[i], nums[left], nums[right]])
325-
# 去重逻辑应该放在找到一个三元组之后,对b 和 c去重
326-
while left != right and nums[left] == nums[left + 1]: left += 1
327-
while left != right and nums[right] == nums[right - 1]: right -= 1
328-
left += 1
328+
result.append([nums[i], nums[left], nums[right]])
329+
330+
# 跳过相同的元素以避免重复
331+
while right > left and nums[right] == nums[right - 1]:
332+
right -= 1
333+
while right > left and nums[left] == nums[left + 1]:
334+
left += 1
335+
329336
right -= 1
330-
return ans
337+
left += 1
338+
339+
return result
331340
```
332-
Python (v3):
341+
(版本二) 使用字典
333342

334343
```python
335344
class Solution:
336345
def threeSum(self, nums: List[int]) -> List[List[int]]:
337-
if len(nums) < 3: return []
338-
nums, res = sorted(nums), []
339-
for i in range(len(nums) - 2):
340-
cur, l, r = nums[i], i + 1, len(nums) - 1
341-
if res != [] and res[-1][0] == cur: continue # Drop duplicates for the first time.
342-
343-
while l < r:
344-
if cur + nums[l] + nums[r] == 0:
345-
res.append([cur, nums[l], nums[r]])
346-
# Drop duplicates for the second time in interation of l & r. Only used when target situation occurs, because that is the reason for dropping duplicates.
347-
while l < r - 1 and nums[l] == nums[l + 1]:
348-
l += 1
349-
while r > l + 1 and nums[r] == nums[r - 1]:
350-
r -= 1
351-
if cur + nums[l] + nums[r] > 0:
352-
r -= 1
346+
result = []
347+
nums.sort()
348+
# 找出a + b + c = 0
349+
# a = nums[i], b = nums[j], c = -(a + b)
350+
for i in range(len(nums)):
351+
# 排序之后如果第一个元素已经大于零,那么不可能凑成三元组
352+
if nums[i] > 0:
353+
break
354+
if i > 0 and nums[i] == nums[i - 1]: #三元组元素a去重
355+
continue
356+
d = {}
357+
for j in range(i + 1, len(nums)):
358+
if j > i + 2 and nums[j] == nums[j-1] == nums[j-2]: # 三元组元素b去重
359+
continue
360+
c = 0 - (nums[i] + nums[j])
361+
if c in d:
362+
result.append([nums[i], nums[j], c])
363+
d.pop(c) # 三元组元素c去重
353364
else:
354-
l +=1
355-
return res
365+
d[nums[j]] = j
366+
return result
356367
```
357368

358369
Go:

‎problems/0017.电话号码的字母组合.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,8 @@ public:
183183
}
184184
};
185185
```
186+
* 时间复杂度: O(3^m * 4^n),其中 m 是对应四个字母的数字个数,n 是对应三个字母的数字个数
187+
* 空间复杂度: O(3^m * 4^n)
186188
187189
一些写法,是把回溯的过程放在递归函数里了,例如如下代码,我可以写成这样:(注意注释中不一样的地方)
188190

‎problems/0018.四数之和.md‎

Lines changed: 41 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -207,72 +207,70 @@ class Solution {
207207
```
208208

209209
Python:
210+
(版本一) 双指针
210211
```python
211-
# 双指针法
212212
class Solution:
213213
def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
214-
215214
nums.sort()
216215
n = len(nums)
217-
res = []
218-
for i in range(n):
219-
if i > 0 and nums[i] == nums[i - 1]: continue # 对nums[i]去重
220-
for k in range(i+1, n):
221-
if k > i + 1 and nums[k] == nums[k-1]: continue # 对nums[k]去重
222-
p = k + 1
223-
q = n - 1
224-
225-
while p < q:
226-
if nums[i] + nums[k] + nums[p] + nums[q] > target: q -= 1
227-
elif nums[i] + nums[k] + nums[p] + nums[q] < target: p += 1
216+
result = []
217+
for i in range(n):
218+
if nums[i] > target and nums[i] > 0 and target > 0:# 剪枝(可省)
219+
break
220+
if i > 0 and nums[i] == nums[i-1]:# 去重
221+
continue
222+
for j in range(i+1, n):
223+
if nums[i] + nums[j] > target and target > 0: #剪枝(可省)
224+
break
225+
if j > i+1 and nums[j] == nums[j-1]: # 去重
226+
continue
227+
left, right = j+1, n-1
228+
while left < right:
229+
s = nums[i] + nums[j] + nums[left] + nums[right]
230+
if s == target:
231+
result.append([nums[i], nums[j], nums[left], nums[right]])
232+
while left < right and nums[left] == nums[left+1]:
233+
left += 1
234+
while left < right and nums[right] == nums[right-1]:
235+
right -= 1
236+
left += 1
237+
right -= 1
238+
elif s < target:
239+
left += 1
228240
else:
229-
res.append([nums[i], nums[k], nums[p], nums[q]])
230-
# 对nums[p]和nums[q]去重
231-
while p < q and nums[p] == nums[p + 1]: p += 1
232-
while p < q and nums[q] == nums[q - 1]: q -= 1
233-
p += 1
234-
q -= 1
235-
return res
241+
right -= 1
242+
return result
243+
236244
```
245+
(版本二) 使用字典
246+
237247
```python
238-
# 哈希表法
239248
class Solution(object):
240249
def fourSum(self, nums, target):
241250
"""
242251
:type nums: List[int]
243252
:type target: int
244253
:rtype: List[List[int]]
245254
"""
246-
# use a dict to store value:showtimes
247-
hashmap = dict()
248-
for n in nums:
249-
if n in hashmap:
250-
hashmap[n] += 1
251-
else:
252-
hashmap[n] = 1
255+
# 创建一个字典来存储输入列表中每个数字的频率
256+
freq = {}
257+
for num in nums:
258+
freq[num] = freq.get(num, 0) + 1
253259

254-
# good thing about using python is you can use set to drop duplicates.
260+
# 创建一个集合来存储最终答案,并遍历4个数字的所有唯一组合
255261
ans = set()
256-
# ans = [] # save results by list()
257262
for i in range(len(nums)):
258263
for j in range(i + 1, len(nums)):
259264
for k in range(j + 1, len(nums)):
260265
val = target - (nums[i] + nums[j] + nums[k])
261-
if val in hashmap:
262-
# make sure no duplicates.
266+
if val in freq:
267+
# 确保没有重复
263268
count = (nums[i] == val) + (nums[j] == val) + (nums[k] == val)
264-
if hashmap[val] > count:
265-
ans_tmp = tuple(sorted([nums[i], nums[j], nums[k], val]))
266-
ans.add(ans_tmp)
267-
# Avoiding duplication in list manner but it cause time complexity increases
268-
# if ans_tmp not in ans:
269-
# ans.append(ans_tmp)
270-
else:
271-
continue
272-
return list(ans)
273-
# if used list() to save results, just
274-
# return ans
269+
if freq[val] > count:
270+
ans.add(tuple(sorted([nums[i], nums[j], nums[k], val])))
275271

272+
return [list(x) for x in ans]
273+
276274
```
277275

278276
Go:

‎problems/0019.删除链表的倒数第N个节点.md‎

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -127,21 +127,29 @@ Python:
127127
# def __init__(self, val=0, next=None):
128128
# self.val = val
129129
# self.next = next
130+
130131
class Solution:
131132
def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
132-
head_dummy = ListNode()
133-
head_dummy.next = head
134-
135-
slow, fast = head_dummy, head_dummy
136-
while(n>=0): #fast先往前走n+1步
133+
# 创建一个虚拟节点,并将其下一个指针设置为链表的头部
134+
dummy_head = ListNode(0, head)
135+
136+
# 创建两个指针,慢指针和快指针,并将它们初始化为虚拟节点
137+
slow = fast = dummy_head
138+
139+
# 快指针比慢指针快 n+1 步
140+
for i in range(n+1):
137141
fast = fast.next
138-
n -= 1
139-
while(fast!=None):
142+
143+
# 移动两个指针,直到快速指针到达链表的末尾
144+
while fast:
140145
slow = slow.next
141146
fast = fast.next
142-
#fast 走到结尾后,slow的下一个节点为倒数第N个节点
143-
slow.next = slow.next.next #删除
144-
return head_dummy.next
147+
148+
# 通过更新第 (n-1) 个节点的 next 指针删除第 n 个节点
149+
slow.next = slow.next.next
150+
151+
return dummy_head.next
152+
145153
```
146154
Go:
147155
```Go

‎problems/0024.两两交换链表中的节点.md‎

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -186,21 +186,20 @@ Python:
186186

187187
class Solution:
188188
def swapPairs(self, head: ListNode) -> ListNode:
189-
res = ListNode(next=head)
190-
pre = res
189+
dummy_head = ListNode(next=head)
190+
current = dummy_head
191191

192-
# 必须有pre的下一个和下下个才能交换,否则说明已经交换结束了
193-
while pre.next and pre.next.next:
194-
cur = pre.next
195-
post = pre.next.next
192+
# 必须有cur的下一个和下下个才能交换,否则说明已经交换结束了
193+
while current.next and current.next.next:
194+
temp = current.next# 防止节点修改
195+
temp1 = current.next.next.next
196196

197-
# pre,cur,post对应最左,中间的,最右边的节点
198-
cur.next = post.next
199-
post.next = cur
200-
pre.next = post
197+
current.next = current.next.next
198+
current.next.next = temp
199+
temp.next = temp1
200+
current = current.next.next
201+
return dummy_head.next
201202

202-
pre = pre.next.next
203-
return res.next
204203
```
205204

206205
Go:

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /