lc1885
满足 d[i] + d[j] > 0 的 d[j] 的最小阈值 target (即 -d[i] + 1 )
lower_bound 找到 d 数组中++从 i+1 位置开始第一个大于等于 target 的元素位置++
数组末尾位置减去该位置得到满足条件的 j 的数量,最后累加到结果中
typedef long long ll;
class Solution {
public:
long long countPairs(vector<int>& nums1, vector<int>& nums2)
{
int n = nums1.size();
vector<int> d(n);
for (int i = 0; i < n; ++i) {
d[i] = nums1[i] - nums2[i];
}
sort(d.begin(), d.end());
ll ret = 0;
for (int i = 0; i < n; ++i) {
int target = -d[i] + 1;
int cnt = d.end() - lower_bound(d.begin() + i + 1, d.end(), target);
ret += cnt;
}
return ret;
}
};
lc1018
class Solution {
public:
vector<bool> prefixesDivBy5(vector<int>& nums)
{
int n = nums.size();
vector<bool> ret(n, false);
int num = 0;
for (int i = 0; i < n; i++)
{
num = (num << 1) + nums[i];
if (num % 5 == 0)
ret[i] = true;
// 防止num过大溢出,对5取余不影响结果,因为++(a*2 + b) % 5 = ((a%5)*2 + b) % 5
num %= 5;++
}
return ret;
}
};
lc1950
单调栈遍历数组,计算每个位置作为最小值时的区间长度
记录对应区间的最大最小值
再通过 *++倒序更新++*得到每个长度下的最大最小值
class Solution {
public:
vector<int> findMaximums(vector<int>& nums) {
int n = nums.size();
//求左右延拓长度,并完成初始化更新
stack<int> sta;
sta.push(-1);
vector<int> ans(n, 0);
for(int i = 0; i < n; ++i){
while(sta.top() != -1 && nums[sta.top()] > nums[i]){
int mi = nums[sta.top()];
sta.pop();
ans[i - sta.top() - 2] = max(ans[i - sta.top() - 2], mi);
}
sta.push(i);
}
while(sta.top() != -1){
int mi = nums[sta.top()];
sta.pop();
ans[n - sta.top() - 2] = max(ans[n - sta.top() - 2], mi);
}
// 倒序更新
for(int i = n - 2;i >= 0; i--){
ans[i] = max(ans[i], ans[i + 1]);
}
return ans;
}
};
画图理清思路 用算法实现出来
lc484
反转连续的D区间

class Solution {
public:
vector<int> findPermutation(string s) {
int n=s.size()+1;
vector<int>ans(n,0);
for(int i=0;i<n;i++)ans[i]=i+1;
int i=0;
while(i<n){
if(s[i]=='D'){
int j=i+1;
while(j<n&&s[j]=='D'){
j++;
}
int len=j-i;
++reverse(ans.begin()+i,ans.begin()+i+len+1);++
++//+1多反转一个++
i=j; //i移到下一个非d的地方
}
else i++;
}
return ans;
}
lc340
滑窗
class Solution {
public:
int lengthOfLongestSubstringKDistinct(string s, int k) {
int n=s.size();
unordered_map<char,int> hash;
int cnt=1,l=0,ret=1;
if(k==0) return 0;
hash[s[0]]++;
for(int i=1;i<n;i++)
{
if(!hash.count(s[i]))
cnt++;
hash[s[i]]++;
while(cnt>k)
{
if(--hash[s[l]]==0)
{
cnt--;++hash.erase(s[l]);++
}
l++;
}
ret=max(ret,i-l+1);
}
return ret;
}
};
lc505
if (p+add<vis[nx][ny])
vis[nx][ny] = p+add;
//update
q.push({nx, ny,p+add})
BFS结合距离记录机制,沿四个方向滚动到底的方式探索迷宫路径
dist数组维护各位置最短距离,仅当新路径更短时更新入队
class Solution
{
int dx[4]={1,-1,0,0};
int dy[4]={0,0,1,-1};
typedef tuple<int,int,int> tiii;
public:
int shortestDistance(vector<vector<int>>& maze, vector<int>& start, vector<int>& destination)
{
int m = maze.size(), n = maze[0].size();
vector<vector<int>> vis(m, vector<int>(n, INT_MAX));
queue<tiii> q;
q.push({start[0], start[1], 0});
vis[start[0]][start[1]] = 0;
int ret=INT_MAX;
while (!q.empty()) {
auto [x, y,p] = q.front();
q.pop();
if (x == destination[0] && y == destination[1]) {
ret=min(ret,p);
}
for (int k = 0; k < 4; ++k) {
int add=0;
int nx = x, ny = y;
// 沿当前方向滚动到底
while (nx + dx[k] >= 0 && nx + dx[k] < m && ny + dy[k] >= 0 && ny + dy[k] < n && maze[nx + dx[k]][ny + dy[k]] == 0) {
nx += dx[k];
ny += dy[k];
add++;
}
if (p+add<vis[nx][ny]) {
vis[nx][ny] = p+add;
//update
q.push({nx, ny,p+add});
}
}
}
return ret==INT_MAX?-1:ret;
}
};