一文掌握三种简单算法(python代码+滑动窗口+单调栈+二分法

263 阅读3分钟

前言

最近用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刷题的一些小小总结!