131.分割回文串
思路:
分为两个函数,一个判断是否为回文串,一个进行回溯。回溯从左往右进行,已遍历的不再重复遍历,因而递归时下标要右移。
代码:
python
class Solution:
# 判断回文串
def isPalindrome(self, ss):
if ss[:] == ss[::-1]:
return True
else:
return False
# 回溯
def backtracking(self, s, startIndex, path, result):
if startIndex >= len(s):
result.append(path[:])
return
for i in range(startIndex, len(s)):
if self.isPalindrome(s[startIndex:i + 1]):
path.append(s[startIndex:i + 1])
self.backtracking(s, i + 1, path, result) # 从下一个开始
path.pop()
def partition(self, s: str) -> List[List[str]]:
result = []
self.backtracking(s, 0, [], result)
return result
35.搜索插入位置
思路:
若选取闭区间,则获得的左右端点都是可用值,且左右端点可以相等;由左右端点获得中间点用于判断,返回左端点。
代码:
python
class Solution:
def searchInsert(self, nums: List[int], target: int) -> int:
left, right = 0, len(nums) - 1
# 这里是闭区间,所以可以相等
while left <= right:
mid = (left + right) // 2
if nums[mid] < target:
left = mid + 1
else:
right = mid - 1
# left 在循环结束时指向的是目标值应该插入的位置,使得插入后数组仍然有序; right 指向的是目标值应该插入位置的前一个位置
return left
74.搜索二维矩阵
方法一:
思路:
借用的上一题的思路,已知一维矩阵如何进行二分查找,二维矩阵就可以用这个思路逐行进行查找。要注意的是,每一个循环都要重新设置left和right,所以定义在循环内
代码:
python
class Solution:
def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:
# 借用的上一题的思路,已知一维矩阵如何进行二分查找,二维矩阵就可以逐行进行查找
for row in range(len(matrix)):
left, right = 0, len(matrix[0]) - 1
while left <= right:
mid = (left + right) // 2
if matrix[row][mid] < target:
left = mid + 1
elif matrix[row][mid] > target:
right = mid - 1
else:
return True
return False
复杂度分析:
时间复杂度:O(mlogn)
空间复杂度:O(1)
方法二:
思路:
把二维矩阵拉成一个一维矩阵进行二分查找。
参考:
代码:
python
class Solution:
def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:
m, n = len(matrix), len(matrix[0])
left, right = 0, m * n - 1
while left <= right:
mid = (left + right) // 2
x = matrix[mid // n][mid % n] # 巧妙!通过整除和取余来得到对应元素
if x == target:
return True
if x < target:
left = mid + 1
else:
right = mid - 1
return False
复杂度分析:
时间复杂度:O(logmn)
空间复杂度:O(1)
34.在排序数组中查找...
思路:
二分查找 红蓝染色法【基础算法精讲 04】_哔哩哔哩_bilibili
代码:
python
class Solution:
def lower_bound(self, nums, target):
left, right = 0, len(nums) - 1
while left <= right:
mid = (left + right) // 2
if nums[mid] < target:
left = mid + 1
else:
right = mid - 1
return left
def searchRange(self, nums: List[int], target: int) -> List[int]:
start = self.lower_bound(nums, target) # 本函数求取的是大于等于target,即下边界
if start == len(nums) or nums[start] != target:
return [-1, -1]
# 上边界相当于是小于等于
end = self.lower_bound(nums, target + 1) - 1
return [start, end]