745 字
4 分钟
Algorithm
2025-09-01

算法链接#

模板(灵神)#

灵茶山艾府-如何科学刷题?

滑动窗口#

规则: 入-更新-出

确认左端点范围#

在[L,R]的范围内, 窗口大小k

那么, R-L+1=k => L=R-k+1

代码#

假定题目是找s中在长度k个字串中最多有多少元音字母

Q: 1456. 定长子串中元音的最大数目 - 力扣(LeetCode)

# Python
class Solution:
def maxVowels(self,s,k):
ans=vowel=0
for i,c in enumerate(s):
# 入
if c in "aeiou":
vowel+=1
if i < k-1:
continue
# 更新
ans=max(ans,vowel)
# 出
if s[i-k+1] in "aeiou":
voewl-=1
return ans
// Java
class Solution:{
public int maxVowels(String S, int k){
// toCharArray(): 将一个字符串(String)转换成一个新的字符数组(char[])
char[] s=S.toCharArray();
int ans =0;
int vowel=0;
for (int i =0;i<s.length;i++){
// 入
if (s[i]=='a'|| ... || s[i]=='u'){
vowel++;
}
if (i<k-1){
continue;
}
// update
ans=Math.max(ans,vowel);
// 出
char out=s[i-k+1];
if (out=='a'||...||out=='u'){
vowel--;
}
}
return ans;
}
}
// JavaScript
var maxVowels=function(s,k){
let ans=0, vowel=0;
for (let i=0;i<s.length;i++){
// in
if (s[i]==='a'||...||s[i]==='u'){
vowel++;
}
if (i<k-1){
continue;
}
// update
ans=Math.max(ans,vowel);
// out
let out=s[i-k+1];
if (out[i]==='a'||...||out[i]==='u'){
vowel--;
}
}
return ans;
};
// C++
class Solution{
public:
int maxVowels:(string s, int k){
int ans=0, vowel=0;
for (int i=0; i<s.size();i++){
// in
if (s[i]=='a'||...||s[i]=='u'){
vowel++;
}
int left=i-k+1;
if (left<0){
continue;
}
// update
ans=max(ans,voewl);
// out
char out=s[left];
if (out[i]=='a'||...||out[i]=='u'){
vowel--;
}
}
return ans;
}
};

二分算法#

怎么判断我写的是哪一种二分?#

答:看 while 循环的条件,如果是 left <= right,就是闭区间;如果是 left < right,就是半闭半开区间;如果是 left + 1 < right,就是开区间。

Q1: 34. 在排序数组中查找元素的第一个和最后一个位置 - 力扣(LeetCode)#

写法: 开区间, 只要left+1<right就可以

# python
class Solution:
def searchRange(self, nums,target):
# 查找当前位置的下标值
start=self.lower_bound(nums,target)
# nums中不存在target值
if start ==len(nums) or nums[start]!=target:
return [-1,-1]
# 查找比当前值大一点的下标值
end=self.lower_bound(nums,target+1)-1
return [start,end]
def lower_bound(self,nums,target):
# 二分查找当前值在数组中的下标是哪
l,r=0,len(nums)
while l+1<r:
mid=(l+r)//2
if nums[mid]>=target:
r=mid
else:
l=mid
return l
//javascript
var searchRange=function(nums,target){
const start=lowerBound(nums,target);
// no exist
if (start===nums.length||nums[start]!==target){
return [-1,-1];
}
const end=lowerBound(nums,target+1)-1;
return [start,end]
}
var lowerBound=function(nums,target){
let l=0,r=nums.length;
while (l+1<r){
const mid=Math.floor((l+r)/2)
if (nums[mid]>=target){
r=mid;
}
else{
l=mid;
}
}
return l;
}
class Solution{
public:
vector<int> searchRange(vector<int>& nums,int target){
int start=lower_bound(nums,target);
if (start==nums.size()||nums[start]!=target){
return {-1,-1}
}
int end=lower_bound(nums,target+1)-1;
return {start,end};
}
int lower_bound(vector<int>nums,int target){
int l,r=0,nums.size();
while (l+1<r){
int mid=l+(r-l)/2;
if (nums[mid]>=target){
r=mid;
}
else{
l=mid;
}
}
return l;
}
};

二分答案#

主要是check难写

求最小数值的答案, 开区间

# Python
class Solution:
def binarySearchMin(self,nums):
def check(mid):
continue
l,r=..,..
while l+1<r:
mid=(l+r)//2
if check(mid):
r=mid
else:
l=mid
return r
# 求最大值不过是把left和right替换一下
# 因为值比较大的贴近于right, 让left趋近right以获取最大值
// JavaScript
var Solution=function(nums){
let l,r=..,..
while (l+1<r){
let mid=Math.floor((l+r)/2);
if check(mid){
r=mid;
}
else{
l=mid;
}
}
return r
};
var check=function(nums){
// TODO
}
//c++
class Solution{
public:
int binarySearchMax(vector<int>& nums){
auto check=[&](int mid){
};
int l,r=..,.;
while (l+1<r){
int mid=l+((r-l)/2);
if (check(mid)){
r=mid;
}
else{
l=mid;
}
}
return l;
}
};

单调栈#

Algorithm
https://kamio-misuzu.github.io/posts/algorithm/
作者
Kamio-Misuzu
发布于
2025-09-01
许可协议
CC BY-NC-SA 4.0