python做题日记(14)
第三十一题
第三十一题的关键点在于理解题目的描述,题目要求求出下一排列,这里的下一个排列是指按照字典序排列,比当前排列大的最小字典序排列。在比较字典序排列时,从左到右逐字符对比。如果字符相同,继续比较下一个字符;如果字符不同,根据字符在字母表中的顺序确定大小。这里对于整数数组也是同样的道理,将两种排列的数字逐一进行比对,如果当前排列数字比原排列对应位置数字大,则当前排列的字典序大于原排列,而大于原排列的最小字典序可以按照如下方式进行查找与排列。
- 先找第一个升序对,确定需要调整的位置。
- 再找比它大的最小数,交换。
- 最后反转后半部分,保证是下一个最小的排列。
因为降序排列是最大的字典序,因此从后向前遍历,找到第一个不是降序排列的升序对,确定需要调整的下标位置,在该位置后找到比调整位置大的最小整数,对其进行对换,再将调整位置后的排列排成升序即可得到比原排列字典序大的最小字典序排列。
class Solution:def nextPermutation(self, nums: list[int]) -> None:"""原地修改,不返回任何内容"""n = len(nums)# 1. 从后往前找到第一个升序对(nums[i] < nums[i+1])i = n - 2while i >= 0 and nums[i] >= nums[i + 1]:i -= 1if i >= 0:# 2. 从后往前找到第一个比 nums[i] 大的数,交换j = n - 1while nums[j] <= nums[i]:j -= 1nums[i], nums[j] = nums[j], nums[i]# 3. 反转 i+1 之后的所有元素left, right = i + 1, n - 1while left < right:nums[left], nums[right] = nums[right], nums[left]left += 1right -= 1
第三十二题
第三十二题需要找到给定只包含括号的字符串中最长的有效括号长度,对于括号这种匹配模式适合用栈这种数据结构对其进行处理,在之前的题目中也用栈对含有括号的字符串进行过处理。对于这道题因为求的是长度,因此在遍历字符串时需要同时得到其下标以及对应元素,故使用enumerate函数实现,如果遇到左括号,就将此处的下标进栈,否则(即遇到右括号),需要弹出栈顶元素,此时有两种情况,一种是栈为空,栈中已经没有任何元素,说明没有可以与当前右括号匹配的左括号,需要将当前右括号的下标加入到栈中,作为下一个合理的括号字符串的起始位置。如果栈中还有元素,说明当前右括号有与之匹配的左括号,因此需要对最大有效长度进行更新,即用当前下标位置减去有效括号字符串的初始位置。此外,栈在初始化时存放索引-1,以便于进行长度计算以及判断当前右括号是否存在与之匹配的左括号。
class Solution:def longestValidParentheses(self, s: str) -> int:stack = [-1] # 栈中存放索引,初始为-1方便计算长度max_len = 0for i, char in enumerate(s):if char == '(':stack.append(i)else:stack.pop()if not stack:stack.append(i)else:max_len = max(max_len, i - stack[-1])return max_len