正文
本博客记录的是 LeetCode 31 到 40 题的题解
之前很少使用的语法
| reverse(nums.begin() + k, nums.end()); |
| stk.top(); |
| stk.size(); |
| stk.pop(); |
| |
| t += to_string(k - j) + s[j]; |
| nums.reverse() |
| nums.append(12) |
| x = nums.pop() |
| nums[-1] |
31. Next Permutation
C++ code
| class Solution { |
| public: |
| |
| void nextPermutation(vector<int>& nums) { |
| int n = nums.size(), l = nums.size() - 1, r = nums.size() - 1; |
| for (int i = n - 2; i >= 0; i -- ) { |
| if (nums[i] < nums[i + 1]) { |
| break; |
| } |
| l -= 1; |
| } |
| int i = l, j = r; |
| while (i < j) { |
| swap(nums[i], nums[j]); |
| i ++, j --; |
| } |
| if (l == 0) { |
| return; |
| } else { |
| for (int i = l; i <= r; i ++ ) { |
| if (nums[i] > nums[l - 1]) { |
| swap(nums[i], nums[l - 1]); |
| break; |
| } |
| } |
| } |
| |
| } |
| }; |
STL写法
| class Solution { |
| public: |
| |
| void nextPermutation(vector<int>& nums) { |
| int n = nums.size(); |
| int k = n - 1; |
| while (k > 0 && nums[k - 1] >= nums[k]) k --; |
| if (k <= 0) { |
| reverse(nums.begin(), nums.end()); |
| } else { |
| int t = k; |
| while (t + 1 < n && nums[k - 1] < nums[t + 1]) t += 1; |
| swap(nums[k - 1], nums[t]); |
| reverse(nums.begin() + k, nums.end()); |
| } |
| |
| } |
| }; |
python code
| class Solution: |
| def nextPermutation(self, nums: List[int]) -> None: |
| """ |
| Do not return anything, modify nums in-place instead. |
| """ |
| n = len(nums) |
| l, r = n - 1, n - 1 |
| for i in range(n - 2, -1, -1): |
| if nums[i] >= nums[i + 1]: |
| l -= 1 |
| else: |
| break |
| i, j = l, r |
| while i < j: |
| nums[i], nums[j] = nums[j], nums[i] |
| i, j = i + 1, j - 1 |
| if l == 0: |
| return |
| else: |
| print(nums) |
| for i in range(l, n): |
| if nums[i] > nums[l - 1]: |
| nums[i], nums[l - 1] = nums[l - 1], nums[i] |
| break |
| print(nums) |
| return |
32. Longest Valid Parentheses
这个题目就是恶心在思路上,即使你能想到需要使用栈来解决到匹配问题,也很难想到上一个未匹配的括号位置,就是他丫的最大的匹配边界。
所以说,我们使用栈来记录他的'('位置,然后查看他所匹配的pop后的top位置,可以得知')'的最大匹配,然后更新res
c++代码
| class Solution { |
| public: |
| int longestValidParentheses(string s) { |
| int res = 0, n = s.size(); |
| stack<int> stk; |
| for (int i = 0, start = -1; i < n; i ++ ) { |
| if (s[i] == '(') stk.push(i); |
| else { |
| if (stk.size()) { |
| stk.pop(); |
| if (stk.size()) { |
| res = max(res, i - stk.top()); |
| } else { |
| res = max(res, i - start); |
| } |
| } else { |
| start = i; |
| } |
| } |
| } |
| return res; |
| } |
| }; |
python 代码
| class Solution: |
| def longestValidParentheses(self, s: str) -> int: |
| n, start, res = len(s), -1, 0 |
| stk = [] |
| for i in range(n): |
| if s[i] == '(': |
| stk.append(i) |
| else: |
| if not stk: |
| start = i |
| else: |
| stk.pop() |
| if not stk: |
| res = max(res, i - start) |
| else: |
| res = max(res, i - stk[-1]) |
| return res |
33. Search in Rotated Sorted Array
两次二分,第一次是找旋转点,第二次是在有序数组中找target
c++代码
| class Solution { |
| public: |
| int get_idx(vector<int>& nums, int l, int r, int target) { |
| int mid; |
| if (target > nums[r] || target < nums[l]){ |
| return -1; |
| } else { |
| while (l < r) { |
| mid = l + r + 1 >> 1; |
| if (nums[mid] <= target) { |
| l = mid; |
| } else { |
| r = mid - 1; |
| } |
| } |
| if (nums[l] == target) { |
| return l; |
| } else { |
| return -1; |
| } |
| } |
| |
| } |
| |
| |
| int search(vector<int>& nums, int target) { |
| |
| int n = nums.size(); |
| if (nums[0] <= nums[n - 1]) { |
| return get_idx(nums, 0, n - 1, target); |
| } else { |
| int l = 0, r = n - 1, mid, x = nums[0]; |
| while (l < r) { |
| mid = l + r >> 1; |
| if (nums[mid] < x) { |
| r = mid; |
| } else { |
| l = mid + 1; |
| } |
| } |
| printf("split mid=%d\n", l); |
| if (target > nums[n - 1]) { |
| return get_idx(nums, 0, l - 1, target); |
| } else { |
| return get_idx(nums, l, n - 1, target); |
| } |
| } |
| } |
| }; |
python 代码
| class Solution: |
| def get_idx(self, nums, l, r, target): |
| if nums[l] > target or nums[r] < target: |
| return -1 |
| while l < r: |
| mid = (l + r + 1) // 2 |
| if nums[mid] <= target: |
| l = mid |
| else: |
| r = mid - 1 |
| return l if nums[l] == target else -1 |
| |
| def search(self, nums: List[int], target: int) -> int: |
| n = len(nums) |
| if nums[0] <= nums[n - 1]: |
| return self.get_idx(nums, 0, n - 1, target) |
| else: |
| l, r = 0, n - 1 |
| while l < r: |
| mid = (l + r) // 2 |
| if nums[mid] < nums[0]: |
| r = mid |
| else: |
| l = mid + 1 |
| if nums[n - 1] >= target: |
| return self.get_idx(nums, l, n - 1, target) |
| else: |
| return self.get_idx(nums, 0, l - 1, target) |
34. Find First and Last Position of Element in Sorted Array
二分查找的基础题目
c++ 代码
| class Solution { |
| public: |
| vector<int> searchRange(vector<int>& nums, int target) { |
| vector<int> res; |
| if (nums.size() <= 0) { |
| return vector<int>{-1, -1}; |
| } |
| int x = target; |
| int l, r, mid, n = nums.size(); |
| l = 0, r = n - 1; |
| |
| while (l < r) { |
| mid = l + r >> 1; |
| if (nums[mid] >= x) { |
| r = mid; |
| } else { |
| l = mid + 1; |
| } |
| } |
| int res1, res2; |
| if (nums[l] != target) { |
| return vector<int> {-1, -1}; |
| } |
| res.push_back(l); |
| |
| l = 0, r = n - 1; |
| while (l < r) { |
| mid = l + r + 1 >> 1; |
| if (nums[mid] <= x) { |
| l = mid; |
| } else { |
| r = mid - 1; |
| } |
| } |
| res.push_back(l); |
| return res; |
| } |
| }; |
python 代码
| class Solution: |
| def searchRange(self, nums: List[int], target: int) -> List[int]: |
| n = len(nums) |
| if n == 0 or target > nums[-1] or target < nums[0]: |
| return [-1, -1] |
| |
| |
| l, r = 0, n - 1 |
| while l < r: |
| mid = (l + r) // 2 |
| if nums[mid] >= target: |
| r = mid |
| else: |
| l = mid + 1 |
| if nums[l] != target: |
| return [-1, -1] |
| res = [l] |
| |
| |
| l, r = 0, n - 1 |
| while l < r: |
| mid = (l + r + 1) // 2 |
| if nums[mid] <= target: |
| l = mid |
| else: |
| r = mid - 1 |
| res.append(l) |
| |
| return res |
35. Search Insert Position
就是寻找大于等于 target 的最小值所在的位置,相当于 34 题一半的代码量
| class Solution: |
| def searchInsert(self, nums: List[int], target: int) -> int: |
| |
| n = len(nums) |
| if nums[-1] < target: |
| return n |
| l, r = 0, n - 1 |
| while l < r: |
| mid = (l + r) // 2 |
| if nums[mid] >= target: |
| r = mid |
| else: |
| l = mid + 1 |
| return l |
| |
36. Valid Sudoku
按照数独给出的3条规则进行暴力模拟即可
python 代码
| class Solution: |
| def isValidSudoku(self, board: List[List[str]]) -> bool: |
| visited = [False] * 12 |
| for i in range(9): |
| for k in range(10): |
| visited[k] = False |
| for j in range(9): |
| if board[i][j] == '.': |
| continue |
| elif visited[int(board[i][j])] == True: |
| return False |
| else: |
| visited[int(board[i][j])] = True |
| for k in range(10): |
| visited[k] = False |
| for j in range(9): |
| if board[j][i] == '.': |
| continue |
| elif visited[int(board[j][i])] == True: |
| return False |
| else: |
| visited[int(board[j][i])] = True |
| for i in range(0, 7, 3): |
| for j in range(0, 7, 3): |
| for k in range(10): |
| visited[k] = False |
| for u in range(3): |
| for v in range(3): |
| if board[i+u][j+v] == '.': |
| continue |
| elif visited[int(board[i+u][j+v])] == True: |
| return False |
| else: |
| visited[int(board[i+u][j+v])] = True |
| return True |
37. Sudoku Solver
暴力 DFS即可,不过需要提前打好表(行列以及小3X3矩阵)进行加速
| class Solution: |
| def solveSudoku(self, a: List[List[str]]) -> None: |
| """ |
| Do not return anything, modify board in-place instead. |
| """ |
| rows = [[False] * 10 for i in range(10)] |
| cols = [[False] * 10 for i in range(10)] |
| place = [[[False] * 10 for i in range(4)] for j in range(4)] |
| for i in range(9): |
| for j in range(9): |
| if a[i][j] == '.': |
| continue |
| else: |
| rows[i][int(a[i][j])] = True |
| cols[j][int(a[i][j])] = True |
| place[i//3][j//3][int(a[i][j])] = True |
| self.dfs(0, 0, a, rows, cols, place) |
| |
| def dfs(self, i, j, a, rows, cols, place): |
| if i >= 9: |
| return True |
| if a[i][j] != '.': |
| if j == 8: |
| return self.dfs(i + 1, 0, a, rows, cols, place) |
| else: |
| return self.dfs(i, j + 1, a, rows, cols, place) |
| for u in range(1, 10): |
| if rows[i][u] == False and cols[j][u] == False and place[i//3][j//3][u] == False: |
| rows[i][u] = cols[j][u] = place[i//3][j//3][u] = True |
| a[i][j] = str(u) |
| if j == 8: |
| if self.dfs(i + 1, 0, a, rows, cols, place): |
| return True |
| elif self.dfs(i, j + 1, a, rows, cols, place): |
| return True |
| rows[i][u] = cols[j][u] = place[i//3][j//3][u] = False |
| a[i][j] = '.' |
| return False |
38. Count and Say
就是查找数字,进行模拟
| class Solution { |
| public: |
| string countAndSay(int n) { |
| string s = "1"; |
| for (int i = 2; i <= n; i ++ ) { |
| string t = ""; |
| for (int j = 0; j < s.size();) { |
| int k = j + 1; |
| while (k < s.size() && s[k] == s[j]) k ++; |
| t += to_string(k - j) + s[j]; |
| j = k; |
| } |
| s = t; |
| } |
| return s; |
| } |
| }; |
| class Solution: |
| def countAndSay(self, n: int) -> str: |
| x = '1' |
| for i in range(1, n): |
| x += ' ' |
| y = '' |
| cnt = 1 |
| for j in range(1, len(x)): |
| if x[j] == x[j - 1]: |
| cnt += 1 |
| else: |
| y += str(cnt) + x[j - 1] |
| cnt = 1 |
| x = y |
| |
| return x |
| |
39. Combination Sum
完全背包板子题
| class Solution: |
| def combinationSum(self, t: List[int], m: int) -> List[List[int]]: |
| f = [[False] * 510 for i in range(40)] |
| f[0][0] = True |
| n = len(t) |
| a = [0] |
| a.extend(t) |
| print(a) |
| for i in range(1, n + 1): |
| for j in range(0, m + 1): |
| if j < a[i]: |
| f[i][j] = f[i - 1][j] |
| else: |
| f[i][j] = (f[i - 1][j] or f[i][j - a[i]]) |
| if f[n][m] == False: |
| return [] |
| res = [] |
| tmp = [] |
| self.dfs(n, m, a, f, tmp, res) |
| return res |
| |
| def dfs(self, i, j, a, f, tmp, res): |
| if j == 0: |
| print(tmp) |
| res.append(tmp[:]) |
| return |
| if j >= a[i] and f[i][j - a[i]] == True: |
| tmp.append(a[i]) |
| self.dfs(i, j - a[i], a, f, tmp, res) |
| tmp.pop() |
| if i >= 1 and f[i - 1][j] == True: |
| self.dfs(i - 1, j, a, f, tmp, res) |
40. Combination Sum II
感觉这个题目出的比较恶心,算法不难,但是出题人有意把你往01背包上绕,但是01背包很难解决方案输出不重复的这个问题,因为它将每一个物品都作为独一无二的,即使他们的 数值一样
所以说,这个题目还是作为多重背包比较好,将 candidate 数组处理成为 unique独一无二的数字配上他出现的次数 cnt 进行多重背包。
但是这个多重背包无法使用 二进制优化,否则还是会出现类似于01背包的问题,解决方案不重复这个问题仍会出现,并很难在时限内解决。
当然也可以直接暴搜
| |
| class Solution { |
| public: |
| vector<vector<int> > ans; |
| vector<int> path; |
| vector<vector<int>> combinationSum2(vector<int>& cs, int target) { |
| sort(cs.begin(), cs.end()); |
| dfs(0, cs, target); |
| return ans; |
| } |
| |
| void dfs(int i, vector<int> &cs, int target) { |
| if (target == 0) { |
| ans.push_back(path); |
| return; |
| } |
| if (i == cs.size()) { |
| return; |
| } |
| int j = i + 1; |
| while (j < cs.size() && cs[i] == cs[j]) j ++; |
| int cnt = j - i; |
| |
| for (int k = 0; k <= cnt && target >= k * cs[i]; k ++ ) { |
| if (k) |
| path.push_back(cs[i]); |
| dfs(j, cs, target - k * cs[i]); |
| } |
| for (int k = 1; k <= cnt && target >= k * cs[i]; k ++ ) |
| path.pop_back(); |
| } |
| }; |
| |
| class Solution: |
| def combinationSum2(self, a: List[int], m: int) -> List[List[int]]: |
| |
| s = [0] * len(a) |
| a.sort() |
| j, s[0], n = 1, 1, len(a) |
| for i in range(1, n): |
| if a[i] == a[i - 1]: |
| s[j - 1] += 1 |
| else: |
| a[j] = a[i] |
| s[j] = 1 |
| j += 1 |
| for i in range(j, n): |
| s.pop() |
| a.pop() |
| |
| |
| f = [[False] * 40 for i in range(110)] |
| f[0][0] = True |
| n = len(a) |
| for i in range(1, n + 1): |
| for j in range(m + 1): |
| k, f[i][j] = 1, f[i - 1][j] |
| while f[i][j] == False and j >= k * a[i - 1] and k <= s[i - 1]: |
| f[i][j] = f[i - 1][j - k * a[i - 1]] |
| k += 1 |
| if not f[n][m]: |
| return [] |
| |
| res, tmp = [], [] |
| self.dfs(n, m, a, s, f, res, tmp) |
| return res |
| |
| def dfs(self, i, j, a, s, f, res, tmp): |
| if j == 0: |
| res.append(tmp[:]) |
| return |
| for k in range(0, s[i - 1] + 1): |
| if j >= k * a[i - 1]: |
| if f[i - 1][j - k * a[i - 1]]: |
| tmp.extend([a[i - 1]] * k) |
| self.dfs(i - 1, j - k * a[i - 1], a, s, f, res, tmp) |
| for u in range(k): |
| tmp.pop() |
| else: |
| break |
| return |
| |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)