字符串类型的笔试题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;
}
};