leetcode
本文最后更新于:2024年2月8日 中午
算法代码阅读
sort
两数之和 -1
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
1 |
|
两数相加 -2
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
1 |
|
无重复字符的最长子串 -3
给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。
1 |
|
寻找两个正序数组的中位数 -4gg
时间复杂度为 \[ \log(m+n) \]
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
class Solution:
def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
def get_k_min(nums1, start1, end1, nums2, start2, end2, k):
remain1 = end1 - start1 + 1
remain2 = end2 - start2 + 1
if remain1 == 0:
return nums2[start2 + k - 1]
if remain2 == 0:
return nums1[start1 + k - 1]
if k == 1:
return min(nums1[start1], nums2[start2])
i = start1 + min(remain1, k // 2) - 1
j = start2 + min(remain2, k // 2) - 1
if nums1[i] <= nums2[j]:
return get_k_min(nums1, i+1, end1, nums2, start2, end2, k - (i - start1 + 1))
else:
return get_k_min(nums1, start1, end1, nums2, j+1, end2, k - (j - start2 + 1))
m, n = len(nums1), len(nums2)
mid1 = (m + n + 1) // 2
mid2 = (m + n + 2) // 2
a = get_k_min(nums1, 0, m-1, nums2, 0, n-1, mid1)
b = get_k_min(nums1, 0, m-1, nums2, 0, n-1, mid2)
return (a + b) / 2
class Solution:
def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
if len(nums1) > len(nums2):
return self.findMedianSortedArrays(nums2, nums1)
#都是可以通过替换两个数组的名称来保证一定的顺序 num2的长度始终是最长的
infinty = 2**40 # 代表正无穷
m, n = len(nums1), len(nums2)
left, right = 0, m
# median1:前一部分的最大值
# median2:后一部分的最小值
median1, median2 = 0, 0
while left <= right: # 一直循环找到一个最大的i满足A[i−1]≤B[j]
# 前一部分包含 nums1[0 .. i-1] 和 nums2[0 .. j-1]
# // 后一部分包含 nums1[i .. m-1] 和 nums2[j .. n-1]
i = (left + right) // 2
j = (m + n + 1) // 2 - i
# nums_im1, nums_i, nums_jm1, nums_j 分别表示 nums1[i-1], nums1[i], nums2[j-1], nums2[j]
# 当一个数组不出现在前一部分时,对应的值为负无穷,就不会对前一部分的最大值产生影响
nums_im1 = (-infinty if i == 0 else nums1[i - 1]) # 注意写法与java不同
# 当一个数组不出现在后一部分时,对应的值为正无穷,就不会对后一部分的最小值产生影响
nums_i = (infinty if i == m else nums1[i])
nums_jm1 = (-infinty if j == 0 else nums2[j - 1])
nums_j = (infinty if j == n else nums2[j])
if nums_im1 <= nums_j:
median1, median2 = max(nums_im1, nums_jm1), min(nums_i, nums_j)
left = i + 1
else:
right = i - 1
return (median1 + median2) / 2 if (m + n) % 2 == 0 else median1
最长回文串
识别出最长的回文串 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# 这个程序复杂度有点高()
class Solution:
def longestPalindrome(self, s: str) -> str:
n = len(s)
if n < 2:
return s
max_len = 1
begin = 0
# dp[i][j] 表示 s[i..j] 是否是回文串
dp = [[False] * n for _ in range(n)] #[False]*n 为一个列表中的False的拼接的展示
for i in range(n):
dp[i][i] = True
# 递推开始
# 先枚举子串长度
for L in range(2, n + 1):
# 枚举左边界,左边界的上限设置可以宽松一些
for i in range(n):
# 由 L 和 i 可以确定右边界,即 j - i + 1 = L 得
j = L + i - 1
# 如果右边界越界,就可以退出当前循环
#i,j 分别为左边界与有边界 在这个循环中,i,j覆盖了所有的值
if j >= n:
break
#检测的顺序为 按照长度来进行检索
#对于i开始的,有多少相同的字符串,同时一开始的时候默认是对于任意一个字符,都可以视为回文串,同时对于任何一个串来说,如果首位相同的话,只需要检测里面两个的字符串是否是相同的.
# 以下开始递归
if s[i] != s[j]:
dp[i][j] = False
else:
if j - i < 3:
dp[i][j] = True
else:
dp[i][j] = dp[i + 1][j - 1]
# 只要 dp[i][L] == true 成立,就表示子串 s[i..L] 是回文,此时记录回文长度和起始位置
if dp[i][j] and j - i + 1 > max_len:
max_len = j - i + 1
begin = i
return s[begin:begin + max_len]
#这是一个从中心向旁边扩散的算法,只要有就可以向外检测
class Solution:
def expandAroundCenter(self, s, left, right):
while left >= 0 and right < len(s) and s[left] == s[right]:
left -= 1
right += 1
return left + 1, right - 1
# 这里表示当前的东西判断完成了
def longestPalindrome(self, s: str) -> str:
start, end = 0, 0
for i in range(len(s)):# 从字符串的长度出发?
left1, right1 = self.expandAroundCenter(s, i, i)
left2, right2 = self.expandAroundCenter(s, i, i + 1)
if right1 - left1 > end - start:
start, end = left1, right1
if right2 - left2 > end - start:
start, end = left2, right2
return s[start: end + 1]
n字形扩散 - 6 (1)
将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行
Z 字形排列。 1
2
3
4
5
6
7
8
9
10
11class Solution:
def convert(self, s: str, numRows: int) -> str:
if numRows < 2: return s
res = ["" for _ in range(numRows)]# 含有numrow个空字符串的结构 同时相当于做了一个初始化
i, flag = 0, -1
for c in s:
res[i] += c
if i == 0 or i == numRows - 1: flag = -flag
i += flag # 通过设置一个flag来控制数字的加入方式
return "".join(res)
插入区间排序 57 - (2)
对于这个数据,只有重合下面的交集, 以及可以直接放入的数组集, 所以一旦有交集 ,可以更新新的left 与 right 放入新的循环中进行更新
1 |
|
三数之和 - (3)
给你一个整数数组 nums ,判断是否存在三元组 [ nums[i], nums[j], nums[k] ] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。
1 |
|
三数之和接近target
1 |
|
四数之和
1 |
|
字母异位词分组
给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。
1 |
|
合并相关的区间
1 |
|