leetcode试题及解析
以下是 LeetCode 第一题到第十题的题目描述、解析和代码:
1. 两数相乘
题目描述:给定两个字符串形式的非负整数 num1 和 num2,返回它们的乘积,同样为字符串形式。
解析:可以将两个字符串转换为数字,然后进行乘法运算,再将结果转换回字符串形式。
代码:
```python
def multiply(num1, num2):
result = int(num1) * int(num2)
return str(result)
```
2. 硬币找零问题
题目描述:假设有几种硬币,如 1 元、3 元、5 元,每种硬币有足够多个。现在要用这些硬币来找零,给定一个要找零的数值,求最少需要多少个硬币。
解析:可以将找零问题转化为图论中的最短路径问题,使用动态规划算法求解。
代码:
```python
def coinChange(amount):
# 初始化 dp 数组
dp = [float('inf')] * (amount + 1)
# 初始化 dp[0] 为 0
dp[0] = 0
# 动态规划,计算每个金额所需的最少硬币数
for i in range(1, amount + 1):
for j in range(1, len(dp)):
if dp[j] <= i:
dp[i] = min(dp[i], dp[j] + 1)
break
return dp[amount]
```
3. 删除链表的节点
题目描述:给定一个链表,删除链表中的节点,节点的删除顺序不限。
解析:删除链表节点需要考虑删除后的节点指向问题,可以使用队列实现。
代码:
```python
def removeNode(head, val):
# 创建一个队列,用于存储待删除的节点
queue = []
# 遍历链表,将待删除的节点加入队列
while head and queue:
if head.val == val:
queue.append(head)
head = head.next
else:
queue.append(head)
head = head.next
# 遍历队列,删除待删除的节点
while queue:
node = queue.pop(0)
if node.next:
node.next.prev = node.prev
else:
head = node.prev
if node.prev:
node.prev.next = node.next
else:
tail = node.next
node.prev = None
node.next = None
return head
```
4. 反转链表
题目描述:给定一个链表,将其反转。
解析:反转链表需要考虑节点指向问题,可以使用递归或迭代实现。
代码:
```python
def reverseList(head):
# 递归实现反转链表
if head and head.next:
new_head = head.next
head.next = reverseList(head.next)
new_head.prev = head
head.prev = None
return new_head
else:
return head
```
5. 求解最大子数组
题目描述:给定一个整数数组,找到其中连续的子数组,使得这个子数组的和最大。
解析:可以使用双指针和滑动窗口的方法求解最大子数组。
代码:
```python
def max_subarray(nums):
# 初始化左右指针
left, right = 0, 0
# 初始化最大和
max_sum = nums[0]
# 遍历数组,更新最大和
while right < len(nums):
max_sum = max(max_sum, nums[right])
while max_sum == nums[left]:
left += 1
max_sum = max_sum - nums[left]
right += 1
return max_sum
```
6. 求解最小的 k 个数
题目描述:给定一个整数数组,找到其中连续的子数组,使得这个子数组的和最小。
解析:可以使用双指针和滑动窗口的方法求解最小 k 个数。
代码:
```python
def min_k_nums(nums, k):
# 初始化左右指针
left, right = 0, 0
# 初始化最小和
min_sum = nums[0]
# 遍历数组,更新最小和
while right < len(nums):
min_sum = min(min_sum, nums[right])
while min_sum == nums[left]:
left += 1
min_sum = min_sum - nums[left]
right += 1
# 返回最小的 k 个数
return nums[left:right:k]
```
7. 求解两个字符串的最长公共子串
题目描述:给定两个字符串 s1 和 s2,找到这两个字符串的最长公共子串。
解析:可以使用动态规划算法求解最长公共子串。
代码:
```python
def longest_common_substring(s1, s2):
# 初始化 dp 数组
dp = [[0] * (len(s2) + 1) for _ in range(len(s1) + 1)]
# 初始化第一行和第一列
for i in range(1, len(s1) + 1):
dp[i][0] = dp[i - 1][0]
for j in range(1, len(s2) + 1):
dp[0][j] = dp[0][j - 1]
# 动态规划,计算最长公共子串
for i in range(1, len(s1) + 1):
for j in range(1, len(s2) + 1):
if s1[i - 1] == s2[j - 1]:
dp[i][j] = dp[i - 1][j - 1] + 1
else:
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])
return dp[len(s1)][len(s2)]
```
8. 求解字符串的子串个数
题目描述:给定一个字符串 s,计算 s 的子串个数。
解析:可以使用哈希表和滑动窗口的方法求解字符串的子串个数。
代码:
```python
def substrings(s):
# 初始化哈希表
hash_table = {}
# 初始化子串个数
count = 0
# 遍历字符串,计算子串个数
for i in range(len(s)):
# 计算当前字符的哈希值
hash_value = hash(s[i:])
# 判断哈希值是否在哈希表中
if hash_value in hash_table:
# 更新子串个数
count += hash_table[hash_value]
# 删除哈希值
del hash_table[hash_value]
else:
# 添加哈希值和子串个数
hash_table[hash_value] = count
count += 1
return count
```
9. 求解矩阵中的路径
题目描述:给定一个二维矩阵,判断其中是否存在一条从左上角到右下角的路径。
解析:可以使用深度优先搜索(DFS)算法求解矩阵中的路径。
代码:
```python
def has_path(matrix):
# 初始化 visit 数组,记录每个位置是否被访问过
visit = [False] * len(matrix)
# 初始化 stack 数组,存储待访问的位置
stack = [(0, 0)]
# 标记当前位置是否可访问
def can_access(x, y):
return x < len(matrix) and y < len(matrix[0]) and not visit[x] and not visit[y]
# 判断矩阵中是否存在从左上角到右下角的路径
while stack:
x, y = stack.pop()
if x == len(matrix) - 1 and y == len(matrix[0]) - 1:
return True
代码:
```python
# 遍历当前位置的相邻位置
for dx, dy in [(1, 0), (-1, 0), (0, 1), (0, -1)]:
# 计算相邻位置的坐标
nx, ny = x + dx, y + dy
# 判断相邻位置是否可访问
if can_access(nx, ny):
# 访问相邻位置,并标记为已访问
visit[nx] = visit[ny] = True
stack.append((nx, ny))
break
return False
```
10. 求解矩阵中的最长上升路径
题目描述:给定一个二维矩阵,找出其中最长的上升路径。
解析:可以使用动态规划算法求解矩阵中的最长上升路径。
代码:
```python
def longest_increasing_path(matrix):
# 初始化 dp 数组,存储每个位置的最长上升路径长度
dp = [[0] * len(matrix[0]) for _ in range(len(matrix))]
# 初始化第一行和第一列的最长上升路径长度
for i in range(1, len(matrix) + 1):
dp[i][0] = dp[i - 1][0]
for j in range(1, len(matrix[0]) + 1):
dp[0][j] = dp[0][j - 1]
# 动态规划,计算每个位置的最长上升路径长度
for i in range(1, len(matrix) + 1):
for j in range(1, len(matrix[0]) + 1):
if matrix[i - 1][j - 1] <= matrix[i][j]:
dp[i][j] = max(dp[i][j], dp[i - 1][j - 1] + 1)
else:
dp[i][j] = max(dp[i][j], dp[i][j - 1])
return dp[len(matrix) - 1][len(matrix[0]) - 1]
```