字符串类型的笔试题1

1. 第k个排列

给出集合 [1,2,3,…,n],其所有元素共有 n! 种排列。

按大小顺序列出所有排列情况,并一一标记,当 n = 3 时, 所有排列如下:

“123”
“132”
“213”
“231”
“312”
“321”

给定 n 和 k,返回第 k 个排列。

示例1
输入: n = 3, k = 3
输出: “213”

class Solution {
public:
    string getPermutation(int n, int k) {
        string s = string("123456789").substr(0,n);
        for(int j = 1; j < k; ++j) {
            next_permutation(s.begin(), s.end()); 
        }
        return s;
    }
};

2. 最小覆盖子串

给你一个字符串 S、一个字符串 T,请在字符串 S 里面找出:包含 T 所有字母的最小子串

输入: S = “ADOBECODEBANC”, T = “ABC”
输出: “BANC”

class Solution {
public:
    unordered_map <char, int> ori, cnt;
    bool check(){
        for (const auto &p: ori) {
            if (cnt[p.first] < p.second) {
                return false;
            }
        }
        return true;
    }
    string minWindow(string s, string t) {
        for (const auto &c: t) {
            ++ori[c];
        }
        int l = 0, r = -1;
        int len = INT_MAX, ansL = -1, ansR = -1;
        while (r < int(s.size())) {
            if (ori.find(s[++r]) != ori.end()) {
                ++cnt[s[r]];
            }
            while (check() && l <= r) {
                if (r - l + 1 < len) {
                    len = r - l + 1;
                    ansL = l;
                }
                if (ori.find(s[l]) != ori.end()) {
                    --cnt[s[l]];
                }
                ++l;
            }
        }
        return ansL == -1 ? string() : s.substr(ansL, len);
    }
};

3. 简化路径

示例1
输入:"/home/"
输出:"/home"
解释:注意,最后一个目录名后面没有斜杠。

示例2
输入:"/…/"
输出:"/"
解释:从根目录向上一级是不可行的,因为根是你可以到达的最高级。

示例3
输入:"/home//foo/"
输出:"/home/foo"
解释:在规范路径中,多个连续斜杠需要用一个斜杠替换。

class Solution {
public:
    string simplifyPath(string path) {
        vector<string>v;
        stringstream iss(path);
        string buf;
        while(getline(iss,buf,'/')){
            if(!buf.empty() && buf != "." && buf != ".."){
                v.push_back(buf);
            }
            else if(!v.empty() && buf == ".."){
                v.pop_back();
            }
        }
        if(v.empty()){
            return "/";
        }
        buf.clear();
        for(string &s:v){
            buf += "/";
            buf += s;
        }
        return buf;
    }
};

4. 解码

一条包含字母 A-Z 的消息通过以下方式进行了编码:

‘A’ -> 1
‘B’ -> 2

‘Z’ -> 26
给定一个只包含数字的非空字符串,请计算解码方法的总数

示例1
输入: “12”
输出: 2
解释: 它可以解码为 “AB”(1 2)或者 “L”(12)。

示例2
输入: “226”
输出: 3
解释: 它可以解码为 “BZ” (2 26), “VF” (22 6), 或者 “BBF” (2 2 6)

思路:动态规划,这个就像分割字符串一样,保证分割的字符串要连续而且要在1和27之间

状态转移方程:dp[i] = dp[i-1] + (dp[i-2] if 双字符合格 else 0)

从第三个字符开始计算,第一个位置初始化1,第二个位置的字符如果是0,则初始化为 0 否则初始化 1

class Solution {
public:
    int numDecodings(string s) {
        int cnt = 0;
        if(s.size() == 0 || (s.size() == 1 && s[0] == '0')) 
            return 0;
        if(s.size() == 1) 
            return 1;
        vector<int> dp(s.size() + 1, 0);
        dp[0] = 1;
        for(int i = 0; i < s.size(); ++i){
            dp[i+1] = s[i] == '0' ? 0 : dp[i];
            if(i > 0 && (s[i-1] == '1' ||\
                (s[i-1] == '2' && s[i] <= '6'))){
                dp[i+1] += dp[i-1];
            }
        }
        return dp.back();
    }
};

5. 字符串压缩算法

例如 string a = “aaabbbccaa” 压缩为 “a3b3c2a2”
如果压缩后的字符串大于原字符串,则返回原字符串

class Solution {
public:
    string compressString(string S) {
        string ret;
        int cnt = 1;
        for(int i = 0;i<S.size();++i){
            if(i != S.size()-1 && S[i] == S[i+1]){
                cnt +=1;
                continue;
            }
            ret.push_back(S[i]);
            ret.append(to_string(cnt));
            cnt =1;
        }
        return ret.size()>=S.size()?S:ret;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序猿的温柔香

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值