前言
最近用python做了一些算法题,简单介绍一下使用到的三种算法!
滑动窗口
滑动窗口的核心思想是维护一个固定大小的窗口,这个窗口在数组或字符串上滑动,通过这种方式来遍历整个数据结构。
在算法使用过程中,涉及到左右两个指针的移动问题。
- 左右指针初始位置一致,右指针向右移直到末尾,左指针根据右指针右移情况进行窗口扩展。
for i in range(len(arr)):#遍历数组长度
while 条件判断:
数据处理,一般添加append、add
移动右指针
例如:无重复字符的最长字串
def lengthOfLongestSubstring(self, s: str) -> int:
occ=set()
n=len(s)
rk,ans=-1,0 #初始化
for i in range(n):
if i!=0:
occ.remove(s[i-1])
while rk+1<n and s[rk+1] not in occ:
#指针移动,同时数值往后移一位(并且不出现在集合中)
occ.add(s[rk+1])
rk+=1
#while一遍完成后,就比较最大的集合数据
ans=max(ans,rk-i+1)
return ans
-
for是最外层移动,是从左到右取一位
-
while是内层循环取长集合
-
最后取最长集合的长度
单调栈
单调栈是一种特殊的栈结构,用于解决一类涉及子数组或子序列的问题。单调栈的核心思想是利用栈来维护一个单调递增或单调递减的序列,从而快速找到满足条件的子数组或子序列。
- 注意python中的栈使用是用list来进行的!
- 使用索引-1来访问栈顶元素。
- 使用索引0来访问栈底元素。
例如:每日温度
- 暴力求解:
ans=[0]*(len(temperatures))
for i in range(len(temperatures)):
flag=0
for j in range(i,len(temperatures)):
if temperatures[i]<temperatures[j] and flag==0:
ans[i]=j-i
flag=1
return ans
这里直接是两个循环直接比较大小,但是当数据太多,限制内存时会影响!
- 单调栈
n=len(temperatures)
ans=[0]*n
stack=[]#这个栈里是放索引,也就是温度的下标
for i in range(n):
temp=temperatures[i]
while stack and temp>temperatures[stack[-1]]:#比较栈和温度
index=stack.pop()#弹出去
ans[index]=i-index
stack.append(i)#如果不满足温度的条件就是往栈里推索引
return ans
这里最不好理解的就是while stack and temp>temperatures[stack[-1]]:,首先要理解stack是一个空栈,这里存放的是数据的索引,所以temperatures[stack[-1]]是取对应索引的数!
这个栈内第一次存放了第一个元素的索引,当这个第二个元素大于第一个元素时,会把第一个元素的索引取出来,这个时候栈内无数据。
二分法
二分法(Binary Search)是一种在有序数组中查找特定元素的高效算法,通过将搜索区间不断地对半划分,逐步缩小搜索范围,直到找到目标值或者搜索区间为空。
这里要了解一下python的//取值,向下取整!
def binary_search(arr, target):
low, high = 0, len(arr) - 1
while low <= high:
mid = (low + high) // 2
if arr[mid] == target:
return mid
elif arr[mid] < target:
low = mid + 1
else:
high = mid - 1
return -1
这里的mid就是取左右边界中向下取整,通过取中间值与目标值来找目标值。并且这种情况,最好是在数组单调的情况下进行操作,可以减少算法的复杂度!
例如:在排序数组中查找元素的第一个和最后一个位置 例如:搜索旋转排序数组 都可以使用上述说到的模板!
总结
leetcode.cn/problems/lo… www.nowcoder.com/creation/ma… leetcode.cn/problems/fi…
最近python刷题的一些小小总结!