5最长回文子串;10正则表达式匹配;17电话号码的字母组合

给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。

示例 1:

输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案。


示例 2:

输入: "cbbd"
输出: "bb"

class Solution {
public:
    string longestPalindrome(string s) {
        //动态规划
        if(s.size()<=1)return s;
        int pos=0,n=1;
        //bool dp[s.size()][s.size()];//不会自动初始化!!!!
        vector<vector<bool>>  dp(s.size(),vector<bool>(s.size()));
        for(int i=0;i<s.size();++i){
            dp[i][i]=true;
            if(i<s.size()-1&&s[i]==s[i+1]){
                dp[i][i+1]=true;
                pos=i;
                n=2;
            }       
        }
        for(int i=2;i<s.size();++i){
            for(int j=0;j+i<s.size();++j){
                if(s[j]==s[j+i] &&dp[j+1][j+i-1]){
                    dp[j][j+i]=true;
                    pos=j;
                    n=i+1;
                }   
            }
        }
        return s.substr(pos,n);
    }
};

manacher马拉车算法->最长回文子串https://segmentfault.com/a/1190000008484167?utm_source=tag-newest

1 转为为奇回文问题

p[i]表示以 i 为中心的最长回文的半径(p[i] - 1正好是原字符串中最长回文串的长度)

3 mx 代表以 id 为中心的最长回文的右边界(注意:s[mx]不属于以id为中心的回文字符串),也就是mx = id + p[id]

class Solution {
public:
    string longestPalindrome(string s) {
        //马拉车算法
        string ss="$#",res="";
        /*
        for(int i=0;i<s.size();++i)
            ss=ss+s[i]+'#';//ss+=s[i]+'#'会报错!*/
        for(auto &i:s) ss=ss+i+'#';
        vector<int> p(ss.size(),1);
        int mx=0,id=0;
        int maxl=0,maxi;
        for(int i=1;i<ss.size();++i){
            if(i<mx) p[i]=min(p[(id<<1)-i],mx-i);
            while(ss[i-p[i]]==ss[i+p[i]]) ++p[i];//头有'$'尾有'\0'所以不用临界判断
            if(p[i]+i>mx){//更新id,mx,注意并不是跟新最大值
                id=i;
                mx=id+p[id];
            }
            if(maxl<p[i]){//不是与p[id]比
                maxl=p[i];
                maxi=i;
            }
        }
        /*if(ss[maxi]!='#')
            res+=ss[maxi];
        for(int i=1;i<p[maxi];++i)
            if(ss[maxi+i]!='#')
                res=ss[maxi+i]+res+ss[maxi+i];
        return res;*/
        return s.substr((maxi-maxl)>>1,maxl-1);
    }
}

给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 '.' 和 '*' 的正则表达式匹配。

'.' 匹配任意单个字符
'*' 匹配零个或多个前面的那一个元素


所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。

说明:


    s 可能为空,且只包含从 a-z 的小写字母。
    p 可能为空,且只包含从 a-z 的小写字母,以及字符 . 和 *。


示例 1:

输入:
s = "aa"
p = "a"
输出: false
解释: "a" 无法匹配 "aa" 整个字符串。


示例 2:

输入:
s = "aa"
p = "a*"
输出: true
解释: 因为 '*' 代表可以匹配零个或多个前面的那一个元素, 在这里前面的元素就是 'a'。因此,字符串 "aa" 可被视为 'a' 重复了一次。


示例 3:

输入:
s = "ab"
p = ".*"
输出: true
解释: ".*" 表示可匹配零个或多个('*')任意字符('.')。


示例 4:

输入:
s = "aab"
p = "c*a*b"
输出: true
解释: 因为 '*' 表示零个或多个,这里 'c' 为 0 个, 'a' 被重复一次。因此可以匹配字符串 "aab"。


示例 5:

输入:
s = "mississippi"
p = "mis*is*p*."
输出: false

class Solution {
public:
    string s,p;//设全局变量和从上层传入&型参数 执行速度差不多
    bool isMatch(string s, string p) {
        this->s=s;
        this->p=p;
        //return helper(s,0,p,0);
        return helper(0,0);
    }
    //bool helper(string &s,int is,string &p, int ip){//不加&会超出时间限制
    bool helper(int is,int ip){
        if(ip>=p.size())return is>=s.size();//这一行和下一行的is<s.size()不好理解
        bool a=is<s.size()&&(s[is]==p[ip]||p[ip]=='.');        
        if(ip+1<p.size()&&p[ip+1]=='*')//当前任意+后一个是*
            return helper(is,ip+2)||a&&helper(is+1,ip);
        else//当前任意+后一个不是*
            return a&&helper(is+1,ip+1);    
    }
};

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。

给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。

示例:

输入:"23"
输出:["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].


说明:
尽管上面的答案是按字典序排列的,但是你可以任意选择答案输出的顺序。

class Solution {
public:
    vector<string> table = {"abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
    vector<string> letterCombinations(string digits) {
        if(digits.size()==0)return {};
        vector<string> res;
        helper(res,"",digits.begin(),digits.end());//多叉树 深度优先遍历
        return res;
    }
    void helper(vector<string> &res,string temp,string::iterator it,string::iterator e){
        if(it!=e){
        string s=table[*it-'2'];
        for(auto &c:s)
            helper(res,temp+c,it+1,e);        
        }
        else
            res.push_back(temp);
        
    }
};
class Solution {//层序
public:
    vector<string> table = {"abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
    vector<string> letterCombinations(string digits) {
        if(digits.size()==0)return {};
        queue<string> q;
        q.push("");
        for(auto &i:digits){
            string s=table[i-'2'];
            int qSize=q.size();
            while(qSize--){
                for(auto &j:s)
                    q.push(q.front()+j);                    
                q.pop();
            }
        }
        vector<string>res;
        while(q.size()){
            res.push_back(q.front());
            q.pop();
        }
        return res;
    }
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值