基础算法-双指针,滑动窗口,位运算,区间离散化

基础算法-双指针,滑动窗口,位运算,区间离散化_第1张图片双指针

两种类型

 基础算法-双指针,滑动窗口,位运算,区间离散化_第2张图片

 

for(int i=0,j=0;i

双指针最核心的性质 可以优化

输入一个字符串 把每个单词输出出来

i找到单词开头

j找到空格

vector rs;
for(int i=0,j=0;i

最长不重复子串

滑动窗口

i,j指针最多走2n步

int left = 0, right = 0;

while (right < s.size()) {
    // 增大窗口
    window.add(s[right]);
    right++;
    
    while (window needs shrink) {
        // 缩小窗口
        window.remove(s[left]);
        left++;
    }
		默认在这里 r 会落在 第一个不符合的位置
		         l 会落在 区间的第一个数
}

 

#include
#include
#include
#include
using namespace std;
typedef pair pii;

// 题目地址: 
int main()
{
    int n=0;
    int m=0;
    cin>>n>>m;
    vector add;
    vector query;
    vector alls;
    for(int i=0;i>a>>b;
        add.push_back({a,b});
        alls.push_back(a);
    }
    for(int i=0;i>a>>b;
        query.push_back({a,b});
        alls.push_back(a);
        alls.push_back(b);
    }
    sort(alls.begin(),alls.end());
    alls.erase(unique(alls.begin(),alls.end()),alls.end());
    vector s(alls.size());

    // 左闭右闭
    // 加

    for(int i=0;i=1)?s[k1-1]:0) <

基础算法-双指针,滑动窗口,位运算,区间离散化_第3张图片最小覆盖子串

基础算法-双指针,滑动窗口,位运算,区间离散化_第4张图片

 

#include
#include
#include
using namespace std;
// 滑动窗口
//  最后一个用例没过  不管了
bool isin(map &has,map &target)
{
    for(auto item:target)
    {
        if(has.count(item.first))
        {
            if(has[item.first] target;
    for(char t1:t)
    {
        if(target.count(t1))
        {
            target[t1]+=1;
        }
        else
        {
            target[t1]=1;
        }
    }

    map has;
    while(r>s;
    string t;
    cin>>t;
    minWindow(s,t);
}

位运算

最常用的两个操作

n的二进制 表示中 第k位数是几 从0开始

 

先把第k位移到最后一位

n>>k

然后与1

&1

结合起来

n>>k&1

lowbit(x) 返回x的最后一位1后面的数 比如10100 返回100

负数即为补码 即为取反+1

基础算法-双指针,滑动窗口,位运算,区间离散化_第5张图片

就可以通过lowbit 求出 一个数中的1的个数

基础算法-双指针,滑动窗口,位运算,区间离散化_第6张图片

 

不断求它的lowbit即可

#include
#include
using namespace std;

// 1001000  求的 1000
int lowbit(int x)
{
    return x&-x;
}
// 1001000 从0位开始 求k位的数
int k_bit(int x,int k)
{
    return x>>k&1;
}
int main()
{
    int n=0;
    cin>>n;
    for(int i=0;i>m;
        int ans=0;
        while(m)
        {
            m-=lowbit(m);
            ans+=1;
        }
        cout<

离散化

比如一个区间 它的大小在

 

但我们仅用到了其中的n个数,因此我们可以将它的区间进行映射

如。0 100 300 300000 4000000 500000000

可以映射成

0 1 2 3 4 5

具体代码如下 使用二分搜索

比如 alls中是我们所有赋值与查询用到的数 有
100 0 300 300 300000 40000000 50000000
我们首先排序alls
sort(alls.begin(),alls.end());
并去除重复值
alls.erase(unique(alls.begin(),alls.end()),alls.end());
然后 查询某个 区间[l1,l2]
就可以将l1,l2 映射成 k1,k2
int k1= lower_bound(alls.begin(),alls.end(),l1)-alls.begin();
int k2= lower_bound(alls.begin(),alls.end(),l2)-alls.begin();

基础算法-双指针,滑动窗口,位运算,区间离散化_第7张图片

 

需要提前知道要有哪些值 查询和用到

如以下这道题

基础算法-双指针,滑动窗口,位运算,区间离散化_第8张图片

基础算法-双指针,滑动窗口,位运算,区间离散化_第9张图片 

 


#include
#include
#include
#include
using namespace std;
typedef pair pii;

int main()
{
    int n=0;
    int m=0;
    cin>>n>>m;
    vector add;
    vector query;
    vector alls;
    for(int i=0;i>a>>b;
        add.push_back({a,b});
        alls.push_back(a);
    }
    for(int i=0;i>a>>b;
        query.push_back({a,b});
        alls.push_back(a);
        alls.push_back(b);
    }
    sort(alls.begin(),alls.end());
    alls.erase(unique(alls.begin(),alls.end()),alls.end());
    vector s(alls.size());

    // 左闭右闭
    // 加

    for(int i=0;i=1)?s[k1-1]:0) <

你可能感兴趣的:(leetcode马拉松,算法,c++,图论)