给定一个字符串 s
和一个字符串数组 words
。 words
中所有字符串长度相同。s
中的串联子串是指一个包含 words
中所有字符串以任意顺序排列连接起来的子串。
- 例如,如果
words = ["ab","cd","ef"]
, 那么"abcdef"
,"abefcd"
,"cdabef"
,"cdefab"
,"efabcd"
, 和"efcdab"
都是串联子串。"acdbef"
不是串联子串,因为它不是任何words
排列的连接。
返回所有串联子串在 s
中的开始索引。你可以以任意顺序返回答案。
标签:哈希表,字符串,滑动窗口
代码:
class Solution:
def findSubstring(self, s: str, words: List[str]) -> List[int]:
haxi = {}
for word in words:
if word not in haxi:
haxi[word] = 1
else:
haxi[word] = haxi[word] + 1
num = len(words)
leng = len(words[0])
res = []
left = 0
while left + num * leng <= len(s):
st = s[left : left + num * leng]
begin = 0
haxi_1 = haxi.copy()
while begin + leng <= num * leng:
word = st[begin : begin + leng]
if word not in haxi_1:
break
else:
haxi_1[word] = haxi_1[word] - 1
begin = begin + leng
flag = True
for key in haxi_1:
if haxi_1[key] != 0:
flag = False
break
if flag:
res.append(left)
left = left + 1
return res
2. 31——下一个排列
整数数组的一个排列就是将其所有成员以序列或线性顺序排列。
- 例如,
arr = [1,2,3]
,以下这些都可以视作arr
的排列:[1,2,3]
、[1,3,2]
、[3,1,2]
、[2,3,1]
。
整数数组的下一个排列是指其整数的下一个字典序更大的排列。更正式地,如果数组的所有排列根据其字典顺序从小到大排列在一个容器中,那么数组的下一个排列就是在这个有序容器中排在它后面的那个排列。如果不存在下一个更大的排列,那么这个数组必须重排为字典序最小的排列(即,其元素按升序排列)。
- 例如,
arr = [1,2,3]
的下一个排列是[1,3,2]
。 - 类似地,
arr = [2,3,1]
的下一个排列是[3,1,2]
。 - 而
arr = [3,2,1]
的下一个排列是[1,2,3]
,因为[3,2,1]
不存在一个字典序更大的排列。
给你一个整数数组 nums
,找出 nums
的下一个排列。必须原地修改,只允许使用额外常数空间。
标签:数组,双指针
代码:
class Solution:
def nextPermutation(self, nums: List[int]) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
i = len(nums) - 1
while i > 0:
if nums[i - 1] >= nums[i]:
i = i - 1
else:
break
if i == 0:
nums.sort()
else:
num1_idx = i - 1
num1 = nums[i - 1]
i = len(nums) - 1
while i > num1_idx:
if nums[i] <= num1:
i = i - 1
else:
break
num2_idx = i
num2 = nums[i]
nums[num1_idx] = num2
nums[num2_idx] = num1
left = num1_idx + 1
right = len(nums) - 1
while left < right:
nums[left], nums[right] = nums[right], nums[left]
left = left + 1
right = right - 1
3. 32——最长有效括号
给你一个只包含 '('
和 ')'
的字符串,找出最长有效(格式正确且连续)括号子串的长度。
标签:栈,字符串,动态规划(目前不会)
代码:
4. 33——搜索旋转排序数组
整数数组 nums
按升序排列,数组中的值互不相同。
在传递给函数之前,nums
在预先未知的某个下标 k
(0 <= k < nums.length
)上进行了旋转,使数组变为 [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]]
(下标从 0 开始计数)。例如, [0,1,2,4,5,6,7]
在下标 3
处经旋转后可能变为 [4,5,6,7,0,1,2]
。
给你旋转后的数组 nums
和一个整数 target
,如果 nums
中存在这个目标值 target
,则返回它的下标,否则返回 -1
。你必须设计一个时间复杂度为 O(log n)
的算法解决此问题。
标签:数组,二分查找
代码:
class Solution:
def search(self, nums: List[int], target: int) -> int:
left = 0
right = len(nums) - 1
while left <= right:
mid = left + (right - left) // 2
if nums[mid] == target:
return mid
if nums[left] <= nums[mid]:
if nums[left] <= target < nums[mid]:
right = mid - 1
else:
left = mid + 1
else:
if nums[mid] < target <= nums[right]:
left = mid + 1
else:
right = mid - 1
return -1
给你一个按照非递减顺序排列的整数数组 nums
,和一个目标值 target
。请你找出给定目标值在数组中的开始位置和结束位置。如果数组中不存在目标值 target
,返回 [-1, -1]
。你必须设计并实现时间复杂度为 O(log n)
的算法解决此问题。
标签:数组,二分查找
代码:
class Solution:
def searchRange(self, nums: List[int], target: int) -> List[int]:
def searchBegin(nums, target):
left = 0
right = len(nums) - 1
while left <= right:
mid = left + (right - left) // 2
if nums[mid] == target:
right = mid - 1
elif nums[mid] < target:
left = mid + 1
elif nums[mid] > target:
right = mid - 1
return left
def searchEnd(nums, target):
left = 0
right = len(nums) - 1
while left <= right:
mid = left + (right - left) // 2
if nums[mid] == target:
left = mid + 1
elif nums[mid] < target:
left = mid + 1
elif nums[mid] > target:
right = mid - 1
return right
if len(nums) == 0 or target not in nums:
return [-1, -1]
else:
return [searchBegin(nums, target), searchEnd(nums, target)]
6. 35——搜索插入位置
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。请必须使用时间复杂度为 O(log n)
的算法。
标签:数组,二分查找
代码:
class Solution:
def searchInsert(self, nums: List[int], target: int) -> int:
left = 0
right = len(nums) - 1
while left <= right:
mid = left + (right - left) // 2
if nums[mid] == target:
return mid
elif nums[mid] < target:
left = mid + 1
elif nums[mid] > target:
right = mid - 1
return left