首页 > 其他分享 >两道题解决滑动窗口问题

两道题解决滑动窗口问题

时间:2023-11-25 10:02:25浏览次数:40  
标签:字符 cnt 窗口 int s2 ++ diff 滑动 两道

定长

567. 字符串的排列 - 力扣(LeetCode)

给你两个字符串 s1 和 s2 ,写一个函数来判断 s2 是否包含 s1 的排列。如果是,返回 true ;否则,返回 false 。

换句话说,s1 的排列之一是 s2 的 子串 。

解题思路

1° 传统套路就是定义两个哈希表,一个存储s1中每个字符的出现次数,记s1的长度为n,另外一个按n的步长遍历s2,并将每次的结果存储这个哈希表中,两哈希表进行比对,若相同则直接return true,若不等,清空s2的哈希表,继续遍历,直到s2遍历完,若不存在,return false。

2° 基于上述题解,我们可以采用滑动窗口模板进行优化。思路是把比对两个哈希表的过程 => 一个哈希 + 一个遍变量 diff == 0? 

3° 同样,记s1的长度为n,以n为一个“窗口”,对于哈希表cnt,把s1出现过的字符--,s2出现过的字符++

4° 遍历哈希表cnt,如果cnt[i] != 0,说明存在不同字符,diff值++,若最终得到的diff==0,说明不存在不同字符,直接return true,否则则从s2的位置n继续遍历

5° 我们需声明两个变量存储每次滑动的离开字符,和新进入的字符,如果离开字符离开窗口之前,cnt[这个字符]==0,说明这个字符之前是平衡的(即s1,s2中这个字符的出现次数相等),字符离开后,则打破了这个平衡,所以diff要++。且cnt[这个字符]--,再次检查离开字符离开之后,cnt[这个字符]==0? 说明这个字符离开后就平衡了,所以diff--,新进入的字符同理。

6° 当窗口滑动过程中出现diff==0,说明s2存在包含s1的子字符串,return true,遍历完仍没有找到则return false

代码实现

bool checkInclusion(char* s1, char* s2) {
    int n = strlen(s1), m = strlen(s2);
    if(n > m){
        return false;
    }
    int cnt[26] = {0};
    for(int i = 0; i < n; i++){
        cnt[s1[i]-'a']--;
        cnt[s2[i]-'a']++;
    }
    int diff = 0;
    for(int i = 0; i < 26; i++){
        if(cnt[i]!=0){
            diff++;
        }
    }
    if(diff==0){
        return true;
    }
    for(int i = n; i < m; i++){
        int x = s2[i]-'a', y = s2[i-n]-'a';
        if(x==y){
            continue;
        }
        if(cnt[x]==0){
            diff++;
        }
        cnt[x]++;
        if(cnt[x]==0){
            diff--;
        }
        if(cnt[y]==0){
            diff++;
        }
        cnt[y]--;
        if(cnt[y]==0){
            diff--;
        }
        if(diff==0){
            return true;
        }
    }
    return false;
}

不定长

面试题 17.18. 最短超串 - 力扣(LeetCode)

假设你有两个数组,一个长一个短,短的元素均不相同。找到长数组中包含短数组所有的元素的最短子数组,其出现顺序无关紧要。

返回最短子数组的左端点和右端点,如有多个满足条件的子数组,返回左端点最小的一个。若不存在,返回空数组。

解题思路

思路大体上同上一题,由hash[small[i]]++, hash[big[i]]--, 和 count == 0 ?来维护滑动窗口,只不过这题是不定长的。需要维护count==0的同时,从窗口的左边开始缩短以求得最短超串。

两道题解决滑动窗口问题_数据结构与算法

代码实现

#define MAX_SIZE 1000000
int* shortestSeq(int* big, int bigSize, int* small, int smallSize, int* returnSize){
    int* ret = (int*)calloc(2, sizeof(int));
    ret[0] = 0;
    ret[1] = INT_MAX;
    int* hash = (int*)calloc(MAX_SIZE, sizeof(int));  
    int count = 0;
    int j = 0;
    for (int i = 0; i < smallSize; i++) {
        hash[small[i]]++;
        count++; 
    }
    for (int i = 0; i < bigSize; i++) {
        hash[big[i]]--;  
        if (hash[big[i]] == 0)
            count--; 
        // 如果统计的不同元素的数量为0,即找到了包含'small'数组中所有元素的子数组,开始压缩窗口
        while (!count) {  
            hash[big[j]]++; 
            if (hash[big[j]] > 0) {
                count++;
                if (ret[1] - ret[0] > i - j) { 
                    ret[0] = j;
                    ret[1] = i;
                }
            }
            j++;
        } 
    }
    *returnSize = ret[1] != INT_MAX ? 2 : 0;
    return ret;
}



标签:字符,cnt,窗口,int,s2,++,diff,滑动,两道
From: https://blog.51cto.com/goku0623/8556834

相关文章

  • app直播源代码,弹出层 加遮罩层 页面禁止滑动
    app直播源代码,弹出层加遮罩层页面禁止滑动加遮罩层大标签下加标签 <div:class="[{introduced:AnimationsPopup}]"></div>scss.introduced{ width:100%; height:100%; position:fixed; top:0; left:0;  z-index:90; transition:all0.15slinea......
  • uniapp+vue3中使用swiper和自定义header实现左右滑动的Tabs功能
    首先创建一个Tabs的Header,包含有一个下划线的指示器,在点击tabs的标题时候下划线会跟着动态的滑动下面是完整的Tabs的代码,可以看到定义了Tabs的background颜色样式,包含tab的宽度indicatorWidth,以及下划线的颜色indicatorColor主要的是tabList属性,通过tabList传入对应的tab数组得......
  • 无涯教程-Tk - 窗口管理
    窗口管理器用于处理顶级窗口。它有助于控制窗口的大小,位置和其他属性。在Tk中用于引用主窗口。window命令的语法如下所示-wmoptionwindowarguments下表显示了Tkwm命令可用的options列表-Sr.No.Syntax&Remark1aspectwindowNameabcd尝试将宽高比保持在a/b与c/d......
  • iframe父子窗口通信
    在业务开发中,经常有需要某个页面嵌入iframe,同时还需要与iframe进行通信。1.子窗口对父窗口发出消息window.parent.postMessage(参数1为发送的消息数据,参数2为可以接受到消息的源)window.parent.postMessage({'type':'自定义事件名',//自定义事件名......
  • 微信小程序 图片处理前后对比 滑动效果
    此处是封装的组件,如果在页面中需要使用的话需要把lifetimes中的attached方法移动到页面onload事件中,同时调整methods方法列表js//component/sliderimg/sliderimg.jsComponent({/***组件的属性列表*/properties:{},data:{clipPath:'polygon(0%......
  • html 图片处理前后 滑动效果
    <!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metahttp-equiv="X-UA-Compatible"content="IE=edge"><metaname="viewport"content="width=device......
  • 【Python】【OpenCV】视频帧和摄像头帧操作 and 窗口显示
    一、读取写入视频文件1importcv223#创建一个视屏捕获对象4videoCapture=cv2.VideoCapture('AVI.avi')56#获取视频的属性值,cv2.CAP_PROP_FPS获取视频帧率7fps=videoCapture.get(cv2.CAP_PROP_FPS)89#cv2.CAP_PROP_FRAME_WIDTH/HEIGHT返回floa......
  • Android 11 -- 关于dialog和悬浮窗导致SystemUI状态栏下拉频繁闪烁(窗口焦点问题)
    bug描述:如果当前app是全屏的属性,导致状态栏隐藏且有dialog弹出时,这个情况下想下拉显示状态栏,会导致状态栏频繁闪烁。//services/core/java/com/android/server/wm/DisplayPolicy.java//更新系统状态栏的属性intupdateSystemUiVisibilityLw(){//Ifthereisnow......
  • osg 设置显示窗口大小
    viewer->realize();//需要realize,否则窗口为nullosgViewer::GraphicsWindow*pWnd=dynamic_cast<osgViewer::GraphicsWindow*>(viewer->getCamera()->getGraphicsContext());if(pWnd){pWnd->set......
  • 修改窗口标题,弹出对话框 (6.0)
    本文学习于B站,记录,借鉴;视频链接:修改窗口标题、弹出对话框_哔哩哔哩_bilibili HWND很明显内部定义的一种数据类型;声明变量名后,获取窗口句柄,虽然我也不清除窗口句柄什么意思,应该是窗口标题开始的位置; 在调用SetWindowText(窗口句柄,字符串);进行修改;未修改前: 修改后: ...........