算法练习题
1. 给定一个 n 个元素有序的整型数组 nums和一个目标值 target,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。
from typing import List class Solution:
# nums: List[int] 变量类型限制,表示整型的列表 def search(self, nums: List[int], target: int) -> int: begin = nums[0] end = len(nums)-1 while begin <= end: mid = (begin + end) // 2 if nums[mid] < target: begin = mid + 1 elif nums[mid] > target: end = mid - 1 else: return mid break else: return -1 print(Solution().search([2,4,5,7,9,11], 3))
2. 整数数组nums按升序排列,数组中的值互不相同,在传递给函数之前,nums在预先未知的某个下标 k(0 <= k < nums.length)上进行了 旋转,例如,[0,1,2,4,5,6,7] 在下标 3处经旋转后可能变为[4,5,6,7,0,1,2]。如果 nums 中存在这个目标值target,则返回它的下标,否则返回-1。
# 二分法 class Solution: def search(self, nums: List[int], target: int) -> int: # 二分法三要素:开始位置、结束位置、中间位置 begin,end = 0, len(nums) - 1 while begin <= end: mid = (begin + end) // 2 if target == nums[mid]: return mid # 需要判断那一边是有序的 if nums[0] <= nums[mid]: if nums[0] <= target < nums[mid]: end = mid - 1 else: begin = mid + 1 else: if nums[mid] < target <= nums[len(nums)-1]: begin = mid + 1 else: end = mid - 1 return -1
3. 二维列表查找,一个有序的二维列表,每一组的最后一个数小于下一组的第一个数,从这个数组中查找元素
# 最简单的方法,时间复杂度高,O = nm² = O(m²) class Solution: def search(self, margi, target): for k, i in enumerate(margi): for m, j in enumerate(i): if j == target: return k,m # 二分查找:时间复杂度为O(logN) class Solution: def search(self, margi, target): h = len(margi) # 列表中列表的数量 # 判断h,当输入一个空数组的时候,就会不存在margi[0],报错 if h == 0: return False w = len(margi[0]) # 二维列表的单位数量 left, right = 0, h * w - 1 # 初始位置和结束位置 while left <= right: mid = (left + right) // 2 i = mid // w # 第几个列表 j = mid % w # 列表中的第几个 if margi[i][j] < target: left = mid + 1 elif margi[i][j] > target: right = mid - 1 else: return i,j return -1
4. 给定一个列表和一个整数,找到列表中两个数的下标,使得两个数之和为给定的整数。例如:[1,2,4,6,7]与目标整数是11,结果为(2,4)
# 方法1: 时间复杂度O(N²) class Solution: def search(self, margi, target): n = len(margi) for i in range(n-1): for j in range(i+1,n): if margi[i] + margi[j] == target: return i,j # 方法二: 二分查找 时间复杂度O(logN) 初始列表无序则修改成橙色代码 class Solution: def binary_select(self, li, left, right, val): while left <= right: mid = (left + right) // 2
# if li[mid][0] == val: # 无序列表 if li[mid] == val: return mid
# if li[mid][0] < val: # 无序列表 elif li[mid] < val: left = mid + 1 else: right = mid - 1 return None def search(self, margi, target):
# new_margi = [[val, ind] for ind, val in enumerate(margi)]
# new_margi.sort(key=lambda x:x[0])
# 以下的margi换成new_margi即可
for i in range(len(margi)): x = margi[i] y = target - x if x <= y: j = self.binary_select(margi, i+1, len(margi)-1, y) else: j = self.binary_select(margi, 0, i-1, b) if j: break return (i,j)
5. 括号匹配问题:输入一个字符串,字符串中有小括号、中括号、大括号,计算该字符串的括号是否匹配:()[]{}和(){([])}符合,([)和()[不符合
# 模拟栈的入栈、出栈、取栈顶 class Stack: def __init__(self): self.stack = [] def push(self, ele): self.stack.append(ele) def pop(self): self.stack.pop() def get_top(self): if len(self.stack) > 0: return self.stack[-1] else: return None def is_empty(self): return len(self.stack) == 0 # 括号匹配函数 def brace_match(str): stack = Stack() match = {'}':'{',']':'[',')':'('} # 字典中的键值对为正确括号匹配 for i in str: if i in {'(','[','{'}: # 如果是左括号,则入栈 stack.push(i) else: # 右括号的三种情况 if stack.is_empty(): # 栈为空直接判断False return False elif stack.get_top() == match[i]: # 栈不为空时栈顶匹配字典,匹配上为一对则出栈 stack.pop() else: # 匹配不上判断False return False if stack.is_empty(): # 直到匹配所有字符后栈为空,则说明括号匹配成功 return True else: return False