python数据结构与算法

0.时间复杂度和空间复杂度

快速判断算法时间复杂度:算法运行时间

1.确定问题规模n

2.循环减半 logn

3.k层关于n的循环 n^k

空间复杂度:评估算法内存占用大小

使用几个变量 O(1)

使用长度为n的一维列表 O(n)

使用m行n列的二维列表 O(mn)

1.递归

递归三步曲:

1.递归参数和返回值

2.终止条件

3.递归

2.二分查找

内置函数 .index() #输入待查找元素 ,输出元素下标,没找到返回None或-1

二分查找的代码

python 复制代码
nums 是有序数组
def binary_search(nums, val):
	left = 0
	right = len(nums)-1
	while left <= right:  #值在闭区间【left,right】找
		mid = (left+right)//2
		if nums[mid]< val:  #待查找的值在mid右
			left = mid +1
		elif nums[mid] > val:  #待查找的值在mid左
			right = mid -1
		else:
			return mid
	return -1  #在nums里面找不到val

3.排序介绍

列表排序 内置函数 sort()

常见的排序算法

差生三人组O(n^2) 好生三人组O(nlogn) 【运行时间:快排<归并<堆排序】 其他排序
冒泡排序 快速排序:极端情况,排序效率低 希尔排序
选择排序 堆排序:在快的排序算法中相对较慢 计数排序
插入排序 归并排序:需要额外的内存开销 基数排序

稳定性:排序后 2 个相等键值的顺序和排序之前它们的顺序相同

3.1 冒泡排序

基本思想

1.列表每两个相邻的数,如果前面比后面大,则交换位置

2.一趟排序完成,则无序区减少一个数, 有序区增加一个数

【每一趟,都把当前无序区最大的数,放到有序区】

python 复制代码
def bubble_sort(nums):
	for i in range(len(nums)-1): # 第 i趟
		exchange = False
		for j in range(len(nums)-i-1):
			if nums[j] > nums[j+1]:
				nums[j], nums[j+1] = nums[j+1], nums[j]   #如果前> 后,则交换
				exchange = True
		
		if  not exchange: #一趟下来,没有发生交换,代表剩下的无序区,已经是有序的
			return 

3.2 选择排序

基本思路:

一趟排序,记录最小的数,放到第一个位置

再一趟排序,记录无序区最小数,放到第二个位置 ...

python 复制代码
def select_sort(nums):
	for i in range(len(nums)-1):
		min_index = i
		for j in range(i+1, len(nums)):
			if nums[j] < nums[min_index]:
				min_index = j
				
		if min_index != i:
			nums[i],nums[min_index] = nums[min_index], nums[i]

3.3 插入排序

基本思路:从无序区来一个数,就插到有序区数组中排好

python 复制代码
def insert_sort(nums):
	for i in range(1, len(nums)):
		temp = nums[i]  #要排的元素
		j = i-1    #有序区的最后一位
		while j >=0 and nums[j]>temp:
			nums[j+1] = nums[j]
			j = j-1
		nums[j+1] = temp 			

3.4 快速排序

基本思路

python 复制代码
def quick_sort(nums, left, right):
	if left< right:   #保证至少两个元素
		mid = partition(data, left, right)  #返回哨兵的位置,在排好的数组里面,哨兵的正确位置
		quick_sort(data, left, mid-1)
		quick_sort(data, mid+1, right)

def partition(nums, left, right):  #复杂度O(n)
	temp = nums[left]
	while left < right:
		while left < right and nums[right] >= temp:  #从右边找比temp小的值
			right -= 1
		nums[left] = nums[right]    #把右边的值写在左边的空位上
		while left < right and nums[left] <= temp:
			left += 1   
		nums[right] = nums[left]   #把左边的值写到右边空位上
	nums[left] = temp  #把temp归位
	return left
	 

3.6 归并排序

基本思路

python 复制代码
def mergeSort(arr):
    if(len(arr)<2):
        return arr
    middle = int(len(arr)/2)
    left, right = arr[0:middle], arr[middle:]
    return merge(mergeSort(left), mergeSort(right))

def merge(left,right):
    result = []
    while left and right:
        if left[0] <= right[0]:
            result.append(left.pop(0))
        else:
            result.append(right.pop(0))
           
    while left:
        result.append(left.pop(0))
    while right:
        result.append(right.pop(0))
    return result

3.5堆排序

大根堆:一颗完全二叉树,满足任一节点都比其孩子节点大

小根堆: ...,...小

堆排序内置模块

python 复制代码
import heapq
 
heap.heapify(nums)   #建堆
heap.heappush(heap, item)
heap.heappop(heap)			

topK问题:n个数,找前k大的数

思路:

1.快排 O(nlogn)

2.冒泡排序 O(nk)

3.堆排序:维护一个k大的小根堆,不断吐出小数 O(nlogk)

力扣:215.数组中第K个最大的元素

给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。

python 复制代码
class Solution:
    def findKthLargest(self, nums: List[int], k: int) -> int:
        
        pivot = nums[0]
        small,equal,big = [],[],[]
        for i in nums:
            if i> pivot:
                big.append(i)
            elif i < pivot:
                small.append(i)
            else:
                equal.append(i)

        if len(big) >= k:
            return self.findKthLargest(big, k)
        elif len(big)< k and len(big) + len(equal)>=k:
            return pivot
        else:
            return self.findKthLargest(small,k-len(big)-len(equal))

力扣:347.前K个高频元素

给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。

python 复制代码
import heapq
class Solution:
    def topKFrequent(self, nums: List[int], k: int) -> List[int]:
        rec = {}
        for i in nums:
            rec[i] = rec.get(i,0) + 1
        stack = []

        for key, value in rec.items():
            heapq.heappush(stack, (value, key))
            if len(stack) > k:
                heapq.heappop(stack)

        ans = [0] * k  
        for i in range(k-1, -1, -1):
            ans[i] = heapq.heappop(stack)[-1]
        return ans
3.7希尔排序
3.8 计数排序
python 复制代码
def count_sort(nums, max_count = 100):
	count = [0 for _ in range(max_count+1)]
	for val in nums:
		count[val]+=1
	nums.clear()
	for index, val in enumerate(count):
		for i in range(val):
			nums.append(index)
	
3.8桶排序

桶排序:表现取决于数据分布

3.9基数排序
相关推荐
尘浮生4 分钟前
Java项目实战II基于Java+Spring Boot+MySQL的智慧养老中心管理系统(开发文档+数据库+源码)
java·开发语言·数据库·spring boot·mysql·微信小程序·maven
9ilk6 分钟前
【分治】--- 快速选择算法
算法
克鲁德战士19 分钟前
【Java并发编程的艺术3】Java内存模型(下)
java·开发语言·redis
爱上语文21 分钟前
Maven快速入门及其POM
java·maven
企业软文推广26 分钟前
软文实战技巧:如何利用媒体平台资源提升品牌影响力?
大数据·python
ZmyCoder31 分钟前
SpringBoot中忽略实体类中的某个属性不返回给前端的方法
java
是小博同学鸭31 分钟前
【面向对象的程序设计——集合框架】主要接口
java·开发语言
世间万物皆对象35 分钟前
Spring Boot Web应用开发:数据访问
java·数据库·spring boot
狐凄1 小时前
Python一些项目bug
windows·python·bug
終不似少年遊*1 小时前
数学知识1
人工智能·学习·算法·机器学习·数学建模