zoukankan      html  css  js  c++  java
  • leetcode_字节跳动_挑战字符串_字符串的排列

      字符串的排列
     

    给定两个字符串 s1 和 s2,写一个函数来判断 s2 是否包含 s1 的排列。

    换句话说,第一个字符串的排列之一是第二个字符串的子串。

    示例1:

    输入: s1 = "ab" s2 = "eidbaooo"
    输出: True
    解释: s2 包含 s1 的排列之一 ("ba").
    

     

    示例2:

    输入: s1= "ab" s2 = "eidboaoo"
    输出: False
    

     

    注意:

    1. 输入的字符串只包含小写字母
    2. 两个字符串的长度都在 [1, 10,000] 之间

    解题思路:
    解决这个问题前可以先回顾下无排列的子串匹配问题,我们当时使用的是实现了DFA状态转移图,当匹配到不同字符时来到不同的状态,知道最终完全匹配。

    (图后补,下次一定)

    而对于有排列的子串问题,我们一样可以构建一个DFA图来实现它,在这时候相比于无排列子串匹配问题,子串的字符顺序就不重要了,思路如下:

    (图后补,下次一定)

    逐个判断长字符串字符:
    (1)不是子串字符,跳过

    (2)是子串字符且没多余重复,记录当前匹配到的长度

    (3)是子串字符但是已经多余了,比如子串“adc”,串“dcda“,第二个d是超出了子串d个数的,从第二个d这个位置往前重新匹配到dc。

    (4)若匹配到的个数已经达到子串长度,完成。

    class Solution {
    public:
        bool checkInclusion(string s1, string s2) {
            
            int len_s1 = s1.length();
            int len_s2 = s2.length();
            if(len_s1>len_s2) return false;
            if(len_s1==0) return true;
            if(len_s1==1){
                for(int i=0;i<len_s2;i++){
                    if(s1[0]==s2[i]) return true;
                }
                return false;
            }
            
            int size[26];//子串字符统计
            int size_tmp[26];//临时子串已用字符统计
            memset(size,0,sizeof(int)*26);
            memset(size_tmp,0,sizeof(int)*26);
                
            map<char,int> mp;
            for(int i=0;i<len_s1;i++){
                mp.insert(pair<char,int>(s1[i],i));//map容器储存,方便查找
                size[s1[i]-'a']++;//记录个数
            }
            
            int len=0;
            
            for(int i=0;i<len_s2;i++){
                //不是子串字符重置跳过
                if(mp.find(s2[i])==mp.end()){
                    len=0;
                    memset(size_tmp,0,sizeof(int)*26);
                    continue;
                }
                
                //是子串字符,判断是否多余出现
                //  cout<<s1[j]<<"--"<<s2[i]<<endl;
                    if(size_tmp[s2[i]-'a']<size[s2[i]-'a']){//存在且还有可用空间
                        len++;
                        size_tmp[s2[i]-'a']++; 
                    }
                    else if(size_tmp[s2[i]-'a']==size[s2[i]-'a']){//没有可用空间了,说明重复了子串一个字符
                       /**当前字符是s1中已经访问过的字符,则往前重新访问记录到无法继续访问**/
                       len=0;
                       memset(size_tmp,0,sizeof(int)*26);
                       int z;
                       for(int z=i;z>=0;z--){
                           if(mp.find(s2[z])==mp.end()) break;//不是子串内容退出
                              
                           if(size_tmp[s2[z]-'a']<size[s2[z]-'a']){//存在且有容量
                                len++;
                                size_tmp[s2[z]-'a']++;
                           }
                           else if(size_tmp[s2[z]-'a']==size[s2[z]-'a']) break; //没有容量了
                       }
                    }
                if(len==len_s1) return true;
            }
            return false;
        }
    };

    此处可以不用map容器,只是一开始查找想到了map,后来规定状态才想到了数组。

    最好的开始时间是以前,其次是现在。
  • 相关阅读:
    格式化数字,将字符串格式的数字,如:1000000 改为 1 000 000 这种展示方式
    jquery图片裁剪插件
    前端开发采坑之安卓和ios的兼容问题
    页面消息提示,上下滚动
    可以使用css的方式让input不能输入文字吗?
    智慧农村“三网合一”云平台测绘 大数据 农业 信息平台 应急
    三维虚拟城市平台测绘 大数据 规划 三维 信息平台 智慧城市
    农业大数据“一张图”平台测绘 大数据 房产 国土 农业 信息平台
    应急管理管理局安全生产预警平台应急管理系统不动产登记 测绘 大数据 规划 科教 三维 信息平台
    地下综合管廊管理平台测绘 大数据 地下管线 三维 信息平台
  • 原文地址:https://www.cnblogs.com/dragonsbug/p/13286226.html
Copyright © 2011-2022 走看看