每天一道LeetCode-----將字串的連續相同的字符合併成一個字元後加個數
阿新 • • 發佈:2019-01-03
Count and Say
原題連結 Count and Say
求出第n個表示式,第n個表示式由第n-1個表示式的讀音構成。如
- 第3個表示式為21,讀作1個2,1個1,所以第4個表示式就是1211。
- 第4個表示式讀作1個1,1個2,2個1,所以第5個表示式為111221。
話說以前有次考試給的就是這一堆字串,沒給說明,問下一個是什麼,當時的想法:這都是什麼鬼?
因為第n個表示式需要第n-1個表示式,所以只能從第一個開始求了,然後每次計算讀音,構成新的表示式,再求下一個表示式…
class Solution {
public:
string countAndSay(int n) {
/* 第一個表示式是1 */
string res("1");
while(--n)
{
/* 下一個新的表示式 */
string tmp("");
/* 當前字元 */
char prev = res[0];
/* 記錄當前字元出現了多少次 */
int cnt = 1;
for(int i = 1; i <= res.size(); ++i)
{
/* 帶等號是為了新增最後一個字元,這樣就不用寫在for外面了 */
if(i < res.size() && res[i] == prev)
{
++cnt;
}
else
{
/*
* 不能寫成tmp += static_cast<char>(cnt + '0') + prev;
* 比如cnt + '0' + '1'不是一個數字字元了
*/
tmp += static_cast<char>(cnt + '0');
tmp += prev;
if(i < res.size())
{
prev = res[i];
cnt = 1;
}
}
}
/* 移動語義,防止拷貝 */
res = std::move(tmp);
}
return res;
}
};
String Compression
原題連結String Compression
給一個字元陣列,把連續一樣的合併,後面增加個數。如果只有1個可以不加個數,圖片例子比較直觀。
要求就是在原字元陣列上做更改,不能有額外的記憶體使用
程式碼如下
class Solution {
public:
int compress(vector<char>& chars) {
if(chars.empty())
return 0;
int res = 0;
/* 記錄當前字元出現的個數,初始為1,第一個字元出現一次 */
int cnt = 1;
int prev_idx = 0;
/* 初始字元,第一個字元 */
char prev = chars[0];
/* 從第二個字元開始,等號是為了解決最後一個字元,不需要寫在for外面 */
for(int i = 1; i <= chars.size(); ++i)
{
if(i < chars.size() && chars[i] == prev)
{
++cnt;
}
else
{
++res;
chars[prev_idx++] = prev;
/* 如果不為1,就需要將出現個數新增到後面 */
if(cnt != 1)
{
int tmp_cnt = cnt;
/* 計算個數有幾位 */
int bits = 1;
while(cnt / 10)
{
++bits;
cnt /= 10;
}
cnt = tmp_cnt;
/* 把個數轉成字元新增到字元後面 */
for(int idx = prev_idx + bits - 1; idx >= prev_idx; --idx)
{
chars[idx] = static_cast<char>(cnt % 10 + '0');
cnt /= 10;
}
res += bits;
prev_idx += bits;
}
if(i < chars.size())
{
cnt = 1;
prev = chars[i];
}
}
}
return res;
}
};