差分
1、原理
差分数组就是原数组后一个减去前一个;最重要的作用是:差分数组的前缀和等于原数组
2、解决问题:快速的区间加法
原数组下标从m到n的各个元素要加某一个数x;那么就对差分数组:diff[m]+=x;diff[n+1]-=x;
while True:
try:
n,m=map(int,input().split())
a=list(map(int,input().split()))
#构造差分数组
diff =[0]*(n+1)
diff[0] = a[0]
for i in range(1,n):
diff[i]= a[i] -a[i-1]
#区间求和转化成差分数组对应位置+x ,-x
for _ in range(m):
x,y,z=map(int,input().split())
x,y=x-1,y-1
diff[x]+=z
diff[y+1]-=z
#对差分数组求前缀和
a[0]=diff[0]
for i in range(1,n):
a[i] = a[i-1] + diff[i]
print(a)
except:
break
贪心
1、算法原理和适用条件
贪心主要解决背包问题,底层原理就是通过局部最优解到达全局最优;
适用于:一个问题可以拆分成很多个子问题;然后每一个子问题都有一个最优解,子问题之间相互独立
利用堆:heapq;下面用gpt介绍一下heapq的用法
heapq
是 Python 标准库中的一个模块,它提供了堆队列算法的实现。堆队列算法是一种特殊的优先队列,其中每个元素都有一个优先级,并且队列按照优先级进行排序。
heapq
模块中的函数允许你使用列表对象有效地实现堆队列算法。这个模块提供了堆操作的基本函数,如 heappush()
, heappop()
, heapify()
, 等等。
以下是一些 heapq
模块中常用的函数:
heappush(heap, item)
: 将元素item
添加到堆heap
中,并保持堆的性质。heappop(heap)
: 从堆heap
中弹出并返回最小的元素(堆顶元素),同时保持堆的性质。heapify(x)
: 将列表x
转换为合法的堆,就地修改x
。heapreplace(heap, item)
: 弹出并返回堆顶元素,然后将元素item
添加到堆中。nlargest(n, iterable[, key])
: 返回可迭代对象iterable
中最大的n
个元素。nsmallest(n, iterable[, key])
: 返回可迭代对象iterable
中最小的n
个元素。
2、简单的例子
1、经典贪心--石子合并问题:每次选择两个最小的
import heapq
n = int(input())
a=lsit(map(int,input().split()))
#利用堆队列算法来获取最小的元素 and 添加元素
#1、把列表a换成堆
heapq.heapify(a)
while len(a) >= 2:
#取出两个最小的元素,和并添加到里面
x= heapq.heappop(a)
y=heapq.heappop(a)
heapq.heappush(a,x+y)
2、分箱问题————每组最多两件:价值不超过w
为了尽可能不浪费空间:大的和小的挨在一起
#输入纪念品价格上限:w,纪念品数量:n;每个纪念品的价格:A
w = int(input())
n = int (input())
a=[]
for i in range (n):
a.append(int(input()))
#最小的和最大的进行匹配,这样在加起来不超过上限的条件下,省空间
a.sort()
ans =0
left =0
right = n-1
while True:
if left = right:
ans +=1
if left < right:
if a[left]+a[right] <= w:
ans +=1
left +=1
right -=1
else:
ans+=1
right -=1
print()
双指针
1、算法原理和步骤
一、反向扫描 左右指针分别指向第一个和最后一个 ,遍历开始之后就左边指针往右移,右边指针往左移:
典型问题————回文字符串 (利用双指针,我们可以直接看这个字符串是不是回文)
s=input()
l =0
r= len(s)-1
ok='Y'
while l <=r:
if s[l]==s[r]:
l +=1
r -=1
else:
ok ="NO"
break
print(ok)
二、同向扫描--滑动窗口
1、算法原理和步骤
滑动窗口左右指针都是从左往右移动的,始终维护一个【l,r】的区间(可闭可开):区间和或者各个元素的个数,左端点往右移动是删除元素,右端点往右移动是添加元素