两天一起394.字符串解码 972.和可被K整除的数字
ps :昨天准备考试,所以断了一天,看来我迟早成为鸽子。。。
394.字符串解码
394. 字符串解码
给定一个经过编码的字符串,返回它解码后的字符串。
编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。
你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。
此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[4] 的输入。
示例:
s = "3[a]2[bc]", 返回 "aaabcbc".
s = "3[a2[c]]", 返回 "accaccacc".
s = "2[abc]3[cd]ef", 返回 "abcabccdcdcdef"
今天这道题的难点我认为是可以任意嵌套,如果不是的话就简单很多。如果是有多层嵌套的话,就首先想到stack,然后我就有点没思路了==。本来说可以简单解出来,但是还是在如何处理string上遇到小困难,2333
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Solution {
public:
inline static string get_digital(size_t & ptr, string &s)
{
string ret;
while(isdigit(s[ptr]))
{
ret.push_back(s[ptr++]);
}
return ret;
}
inline static string get_string(vector<string> &v)
{
string ret;
for (const auto & s : v)
{
ret += s;
}
return ret;
}
string decodeString(string s) const {
vector<string> stk;
size_t ptr = 0;
while (ptr < s.size())
{
const auto cur = s[ptr];
if (isdigit(cur))
{
auto digital = get_digital(ptr, s);
stk.push_back(digital);
}
else if (isalpha(cur) || cur == '[')
{
stk.emplace_back(1, s[ptr++]);
}
else
{
++ptr;
vector<string> sub;
while (stk.back() != "[")
{
sub.push_back(stk.back());
stk.pop_back();
}
reverse(sub.begin(), sub.end());
stk.pop_back();
auto rep_time = stoi(stk.back());
stk.pop_back();
string t;
const auto o = get_string(sub);
while (rep_time--)
{
t += o;
}
stk.push_back(t);
}
}
return get_string(stk);
}
};
int main()
{
string s = "2[abc]3[cd]ef";
Solution ss;
cout << ss.decodeString(s);
return 0;
}
972.和可被K整除的数字
974. 和可被 K 整除的子数组
给定一个整数数组 A,返回其中元素之和可被 K 整除的(连续、非空)子数组的数目。
示例:
输入:A = [4,5,0,-2,-3,1], K = 5
输出:7
解释:
有 7 个子数组满足其元素之和可被 K = 5 整除:
[4, 5, 0, -2, -3, 1], [5], [5, 0], [5, 0, -2, -3], [0], [0, -2, -3], [-2, -3]
其实一开始真的就是想不出除了暴力法的方法,然后看了官方题解才知道可以用同余定理去搞,然后用hash表记住每一次的余数就好,然后就是遍历过程中记录自己的值。先上代码
#include <iostream>
#include <unordered_map>
using namespace std;
class Solution
{
public:
int subarraysDivByK(vector<int>& A, int K)
{
unordered_map<int, int> map = { {0, 1} };
auto sum = 0, ans = 0;
for (const auto num : A)
{
sum += num;
auto mod = (sum % K + K) % K;
ans += map[mod];
++map[mod];
}
return ans;
}
};
int main()
{
vector<int> vec{ 4,5,0,-2,-3,1 };
Solution s;
cout << s.subarraysDivByK(vec, 5);
return 0;
}
只要是相同的余数都会被记录,然后有相同余数必定是一个可被整除的子数列。这样就能在线性时间解决。