常考100

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]
其他排序排序算法集合
  1. 选择排序
  2. 希尔排序
  3. 计数排序
  4. 桶排序
  5. 其余排序
    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.合并区间
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/db1795c913b449edac4e19af848f523a.pn

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)))

二分查找

双指针

滑动窗口

2.链表

链表经典

链表排序

链表双指针

3.堆栈

基础题

单调栈

4.队列

基础题

优先队列

5.哈希表

6.字符串

7.树

经典

二叉搜索树

8.图论

深度优先搜索

广度优先搜索

10.动态规划

11.基础算法

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值