1. 数组
数组基础
54.螺旋数组
class Solution:
def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
res = []
left, right, top, bottom = 0,len(matrix[0])-1, 0,len(matrix)-1
while True:
for i in range(left, right+1):
res.append(matrix[top][i])
top += 1
if top>bottom: break
for i in range(top, bottom+1):
res.append(matrix[i][right])
right -= 1
if right < left : break
for i in range(right, left-1,-1):
res.append(matrix[bottom][i])
bottom -= 1
if bottom < top: break
for i in range(bottom, top-1, -1):
res.append(matrix[i][left])
left += 1
if left > right: break
return res
48.旋转图像
class Solution:
def rotate(self, matrix: List[List[int]]) -> None:
"""
Do not return anything, modify matrix in-place instead.
"""
temp = copy.deepcopy(matrix)
for i in range(len(temp)):
for j in range(len(temp[0])):
matrix[i][j] = temp[len(matrix)-1-j][i]
return matrix
排序类算法
快速排序模板 : 时间复杂度O(nlogn) 空间复杂度O(n)
对整个数组,排序
def quick_sort(array, left, right):
if left < right:
mid = randomPartition(array, left, right)
quick_sort(array, left, mid)
quick_sort(array, mid+1, right)
return array
def partition(array, left, right):
pivot = array[left]
while left < right:
while (left <right and array[right]>= pivot):
right -= 1
array[left] = array[right]
while (left< right and array[left] <= pivot):
left += 1
array[right] = array[left]
array[left] = pivot
return left
def randomPartition(arr, left, right):
pivot_idx = random.randint(left, right) # 随机选择pivot
arr[left], arr[pivot_idx] = arr[pivot_idx], arr[left] # pivot放置到最左边
return partition(arr, left, right)
找第K大的元素
'''快速排序'''
class Solution:
def findKthLargest(self, nums: List[int], k: int) -> int:
def partition(nums, left, right):
pivot = nums[left]
while left< right:
while (left< right and nums[right]>=pivot):
right -= 1
nums[left] = nums[right]
while (left<right and nums[left] <= pivot):
left += 1
nums[right] = nums[left]
nums[left] = pivot
return left
def randomPartition(nums, left, right): # 随机选择pivot,防止最坏情况nums是降序
pivot_index = random.randint(left, right)
nums[left], nums[pivot_index] = nums[pivot_index], nums[left]
return partition(nums, left, right)
def topKSplit(nums, left, right, k): #找到第k小的元素,如果是第1小,则index=0
mid = randomPartition(nums, left, right)
if mid == k-1:
return nums[mid]
elif mid < k-1:
return topKSplit(nums, mid+1, right, k)
else:
return topKSplit(nums, left, mid-1, k)
n = len(nums)
return topKSplit(nums, 0, n-1, n-k+1) #第k大=第n-k+1小
归并排序模板:时间复杂度O(nlogn) 空间复杂度O(n)
class Solution:
def merge(self, left_nums: [int], right_nums: [int]):
nums = []
left_i, right_i = 0, 0
while left_i < len(left_nums) and right_i < len(right_nums):
if left_nums[left_i] < right_nums[right_i]:
nums.append(left_nums[left_i])
left_i += 1
else:
nums.append(right_nums[right_i])
right_i += 1
while left_i < len(left_nums):
nums.append(left_nums[left_i])
left_i += 1
while right_i < len(right_nums):
nums.append(right_nums[right_i])
right_i += 1
return nums
def mergeSort(self, nums: [int]) -> [int]:
# 数组元素个数小于等于 1 时,直接返回原数组
if len(nums) <= 1:
return nums
mid = len(nums) // 2
left_nums = self.mergeSort(nums[0: mid]) # 递归将左子数组进行分解和排序
right_nums = self.mergeSort(nums[mid:]) # 递归将右子数组进行分解和排序
return self.merge(left_nums, right_nums)
def sortArray(self, nums: [int]) -> [int]:
return self.mergeSort(nums)
堆排序:时间复杂度O(nlogn) 空间复杂度O(1)
##升序堆排序,思路如下:
# 1. 先建立大顶堆
# 2. 让堆顶最大元素与最后一个交换,然后调整第一个元素到倒数第二个元素,这一步获取最大值
# 3. 再交换堆顶元素与倒数第二个元素,然后调整第一个元素到倒数第三个元素,这一步获取第二大值
# 4. 以此类推,直到最后一个元素交换之后完毕。
获取第K的的数
class Solution:
def findKthLargest(self, nums: List[int], k: int) -> int:
def maxHepify(arr, i, end): # 大顶堆
j = 2*i + 1 # j为i的左子节点【建堆时下标0表示堆顶】
while j <= end: # 自上而下进行调整
if j+1 <= end and arr[j+1] > arr[j]: # i的左右子节点分别为j和j+1
j += 1 # 取两者之间的较大者
if arr[i] < arr[j]: # 若i指示的元素小于其子节点中的较大者
arr[i], arr[j] = arr[j], arr[i] # 交换i和j的元素,并继续往下判断
i = j # 往下走:i调整为其子节点j
j = 2*i + 1 # j调整为i的左子节点
else: # 否则,结束调整
break
n = len(nums)
# 建堆【大顶堆】
for i in range(n//2-1, -1, -1): #从0开始算起,从第一个非叶子节点n//2-1开始依次往上进行建堆的调整
maxHepify(nums, i, n-1)
# 排序:依次将堆顶元素(当前最大值)放置到尾部,并调整堆
# k-1次重建堆(堆顶元素),或 k次交换到尾部(倒数第k个元素)
for j in range(n-1, n-k-1, -1):
nums[0], nums[j] = nums[j], nums[0] # 堆顶元素(当前最大值)放置到尾部j
maxHepify(nums, 0, j-1) # j-1变成尾部,并从堆顶0开始调整堆
return nums[-k]
其他排序排序算法集合
- 选择排序
- 希尔排序
- 计数排序
- 桶排序
- 其余排序
169.多数元素
class Solution:
def majorityElement(self, nums: List[int]) -> int:
vote = 0
for i in nums:
if vote == 0:
zhong = i
if i == zhong:
vote += 1
elif vote >0:
vote -= 1
return zhong
分治思想
class Solution:
def majorityElement(self, nums: List[int]) -> int:
def get_mode(low, high): #拿到[low...right]的众数
if low == high:
return nums[low]
mid = low + (high - low) // 2
left_mod = get_mode(low, mid)
right_mod = get_mode(mid + 1, high)
if left_mod == right_mod:
return left_mod
left_mod_cnt, right_mod_cnt = 0, 0
for i in range(low, high + 1):
if nums[i] == left_mod:
left_mod_cnt += 1
if nums[i] == right_mod:
right_mod_cnt += 1
if left_mod_cnt > right_mod_cnt:
return left_mod
return right_mod
return get_mode(0, len(nums) - 1)
56.合并区间
class Solution:
def merge(self, intervals: List[List[int]]) -> List[List[int]]:
intervals.sort()
res = []
for i in intervals:
if not res or i[0] > res[-1][1]:
res.append(i)
else:
res[-1][1] = max(res[-1][1] ,i[1])
return res
136.只出现一次的数字
class Solution:
def singleNumber(self, nums: List[int]) -> int:
x = 0
for i in nums:
x ^= i
return x
179。最大数
import functools
class Solution:
def largestNumber(self, nums: List[int]) -> str:
def cmp(a, b):
if a + b == b + a:
return 0
elif a + b > b + a: #不变顺序
return 1
else:
return -1 #变顺序
nums_s = list(map(str, nums))
nums_s.sort(key=functools.cmp_to_key(cmp), reverse=True) #降序排
return str(int(''.join(nums_s)))