leetcode試題及解析
以下是 LeetCode 第一題到第十題的題目描述、解析和代碼:
1. 兩數(shù)相乘
題目描述:給定兩個(gè)字符串形式的非負(fù)整數(shù) num1 和 num2,返回它們的乘積,同樣為字符串形式。
解析:可以將兩個(gè)字符串轉(zhuǎn)換為數(shù)字,然后進(jìn)行乘法運(yùn)算,再將結(jié)果轉(zhuǎn)換回字符串形式。
代碼:??
```python??
def multiply(num1, num2):??
? ? result = int(num1) * int(num2)??
? ? return str(result)??
```
2. 硬幣找零問題
題目描述:假設(shè)有幾種硬幣,如 1 元、3 元、5 元,每種硬幣有足夠多個(gè)?,F(xiàn)在要用這些硬幣來找零,給定一個(gè)要找零的數(shù)值,求最少需要多少個(gè)硬幣。
解析:可以將找零問題轉(zhuǎn)化為圖論中的最短路徑問題,使用動(dòng)態(tài)規(guī)劃算法求解。
代碼:??
```python??
def coinChange(amount):??
? ? # 初始化 dp 數(shù)組??
? ? dp = [float('inf')] * (amount + 1)??
? ? # 初始化 dp[0] 為 0??
? ? dp[0] = 0??
? ? # 動(dòng)態(tài)規(guī)劃,計(jì)算每個(gè)金額所需的最少硬幣數(shù)??
? ? 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. 刪除鏈表的節(jié)點(diǎn)
題目描述:給定一個(gè)鏈表,刪除鏈表中的節(jié)點(diǎn),節(jié)點(diǎn)的刪除順序不限。
解析:刪除鏈表節(jié)點(diǎn)需要考慮刪除后的節(jié)點(diǎn)指向問題,可以使用隊(duì)列實(shí)現(xiàn)。
代碼:??
```python??
def removeNode(head, val):??
? ? # 創(chuàng)建一個(gè)隊(duì)列,用于存儲(chǔ)待刪除的節(jié)點(diǎn)??
? ? queue = []??
? ? # 遍歷鏈表,將待刪除的節(jié)點(diǎn)加入隊(duì)列??
? ? while head and queue:??
? ? ? ? if head.val == val:??
? ? ? ? ? ? queue.append(head)??
? ? ? ? ? ? head = head.next??
? ? ? ? else:??
? ? ? ? ? ? queue.append(head)??
? ? ? ? ? ? head = head.next??
? ? # 遍歷隊(duì)列,刪除待刪除的節(jié)點(diǎn)??
? ? 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. 反轉(zhuǎn)鏈表
題目描述:給定一個(gè)鏈表,將其反轉(zhuǎn)。
解析:反轉(zhuǎn)鏈表需要考慮節(jié)點(diǎn)指向問題,可以使用遞歸或迭代實(shí)現(xiàn)。
代碼:??
```python??
def reverseList(head):??
? ? # 遞歸實(shí)現(xiàn)反轉(zhuǎn)鏈表??
? ? 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. 求解最大子數(shù)組
題目描述:給定一個(gè)整數(shù)數(shù)組,找到其中連續(xù)的子數(shù)組,使得這個(gè)子數(shù)組的和最大。
解析:可以使用雙指針和滑動(dòng)窗口的方法求解最大子數(shù)組。
代碼:??
```python??
def max_subarray(nums):??
? ? # 初始化左右指針??
? ? left, right = 0, 0??
? ? # 初始化最大和??
? ? max_sum = nums[0]??
? ? # 遍歷數(shù)組,更新最大和??
? ? 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 個(gè)數(shù)
題目描述:給定一個(gè)整數(shù)數(shù)組,找到其中連續(xù)的子數(shù)組,使得這個(gè)子數(shù)組的和最小。
解析:可以使用雙指針和滑動(dòng)窗口的方法求解最小 k 個(gè)數(shù)。
代碼:??
```python??
def min_k_nums(nums, k):??
? ? # 初始化左右指針??
? ? left, right = 0, 0??
? ? # 初始化最小和??
? ? min_sum = nums[0]??
? ? # 遍歷數(shù)組,更新最小和??
? ? 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 個(gè)數(shù)??
? ? return nums[left:right:k]??
```
7. 求解兩個(gè)字符串的最長公共子串
題目描述:給定兩個(gè)字符串 s1 和 s2,找到這兩個(gè)字符串的最長公共子串。
解析:可以使用動(dòng)態(tài)規(guī)劃算法求解最長公共子串。
代碼:??
```python??
def longest_common_substring(s1, s2):??
? ? # 初始化 dp 數(shù)組??
? ? 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]??
? ? # 動(dòng)態(tài)規(guī)劃,計(jì)算最長公共子串??
? ? 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. 求解字符串的子串個(gè)數(shù)
題目描述:給定一個(gè)字符串 s,計(jì)算 s 的子串個(gè)數(shù)。
解析:可以使用哈希表和滑動(dòng)窗口的方法求解字符串的子串個(gè)數(shù)。
代碼:??
```python??
def substrings(s):??
? ? # 初始化哈希表??
? ? hash_table = {}??
? ? # 初始化子串個(gè)數(shù)??
? ? count = 0??
? ? # 遍歷字符串,計(jì)算子串個(gè)數(shù)??
? ? for i in range(len(s)):??
? ? ? ? # 計(jì)算當(dāng)前字符的哈希值??
? ? ? ? hash_value = hash(s[i:])??
? ? ? ? # 判斷哈希值是否在哈希表中??
? ? ? ? if hash_value in hash_table:??
? ? ? ? ? ? # 更新子串個(gè)數(shù)??
? ? ? ? ? ? count += hash_table[hash_value]??
? ? ? ? ? ? # 刪除哈希值??
? ? ? ? ? ? del hash_table[hash_value]??
? ? ? ? else:??
? ? ? ? ? ? # 添加哈希值和子串個(gè)數(shù)??
? ? ? ? ? ? hash_table[hash_value] = count??
? ? ? ? ? ? count += 1??
? ? return count??
```
9. 求解矩陣中的路徑
題目描述:給定一個(gè)二維矩陣,判斷其中是否存在一條從左上角到右下角的路徑。
解析:可以使用深度優(yōu)先搜索(DFS)算法求解矩陣中的路徑。
代碼:??
```python??
def has_path(matrix):??
? ? # 初始化 visit 數(shù)組,記錄每個(gè)位置是否被訪問過??
? ? visit = [False] * len(matrix)??
? ? # 初始化 stack 數(shù)組,存儲(chǔ)待訪問的位置??
? ? stack = [(0, 0)]??
? ? # 標(biāo)記當(dāng)前位置是否可訪問??
? ? 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? ??
? ? ? ? ? ? # 遍歷當(dāng)前位置的相鄰位置? ??
? ? ? ? ? ? for dx, dy in [(1, 0), (-1, 0), (0, 1), (0, -1)]:? ??
? ? ? ? ? ? ? ? # 計(jì)算相鄰位置的坐標(biāo)? ??
? ? ? ? ? ? ? ? nx, ny = x + dx, y + dy? ??
? ? ? ? ? ? ? ? # 判斷相鄰位置是否可訪問? ??
? ? ? ? ? ? ? ? if can_access(nx, ny):? ??
? ? ? ? ? ? ? ? ? ? # 訪問相鄰位置,并標(biāo)記為已訪問? ??
? ? ? ? ? ? ? ? ? ? visit[nx] = visit[ny] = True? ??
? ? ? ? ? ? ? ? ? ? stack.append((nx, ny))? ??
? ? ? ? ? ? ? ? ? ? break? ??
? ? return False? ??
```
10. 求解矩陣中的最長上升路徑
題目描述:給定一個(gè)二維矩陣,找出其中最長的上升路徑。
解析:可以使用動(dòng)態(tài)規(guī)劃算法求解矩陣中的最長上升路徑。
代碼:? ??
```python? ??
def longest_increasing_path(matrix):? ??
? ? # 初始化 dp 數(shù)組,存儲(chǔ)每個(gè)位置的最長上升路徑長度? ??
? ? 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]? ??
? ? # 動(dòng)態(tài)規(guī)劃,計(jì)算每個(gè)位置的最長上升路徑長度? ??
? ? 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]? ??
```