我们可以在适当的位置进行游程编码(假设输入数组非常大) 我们可以为AAAABBBBCCCCDDDD等案例做 A4B4C4D4
但是对于像ABCDEFG这样的情况怎么办呢? 其中输出为A1B1C1D1E1F1G1
答案 0 :(得分:1)
C ++解决方案O(n)时间O(1)空间
string runLengthEncode(string str)
{
int len = str.length();
int j=0,k=0,cnt=0;
for(int i=0;i<len;i++)
{
j=i;
cnt=1;
while(i<len-1 && str[i]==str[i+1])
{
i++;
cnt++;
}
str[k++]=str[j];
string temp =to_string(cnt);
for(auto m:temp)
str[k++] = m;
}
str.resize(k);
return str;
}
答案 1 :(得分:1)
我的第一个想法是从最后开始编码,所以我们将使用空闲空间(如果有的话),之后我们可以将编码数组移到开头。这种方法的一个问题是它不适用于AAAAB
,因为没有空闲空间(A4B1不需要它),我们将尝试在第一次迭代时编写AAAAB1。
以下是更正后的解决方案: (让我们假设序列是AAABBC)
每一步都是O(n),据我所知,只需要不断的额外内存。
限制:
答案 2 :(得分:0)
null用于指示哪些项为空,并且将被忽略以进行编码。你也不能编码数字(AAA2222 =&gt; A324 =&gt; 324倍'A',但它是A3; 24)。您的问题会提出更多问题。
这是C#中的“解决方案”
public static void Encode(string[] input)
{
var writeIndex = 0;
var i = 0;
while (i < input.Length)
{
var symbol = input[i];
if (symbol == null)
{
break;
}
var nextIndex = i + 1;
var offset = 0;
var count = CountSymbol(input, symbol, nextIndex) + 1;
if (count == 1)
{
ShiftRight(input, nextIndex);
offset++;
}
input[writeIndex++] = symbol;
input[writeIndex++] = count.ToString();
i += count + offset;
}
Array.Clear(input, writeIndex, input.Length - writeIndex);
}
private static void ShiftRight(string[] input, int nextIndex)
{
var count = CountSymbol(input, null, nextIndex, (a, b) => a != b);
Array.Copy(input, nextIndex, input, nextIndex + 1, count);
}
private static int CountSymbol(string[] input, string symbol, int nextIndex)
{
return CountSymbol(input, symbol, nextIndex, (a, b) => a == b);
}
private static int CountSymbol(string[] input, string symbol, int nextIndex, Func<string, string, bool> cmp)
{
var count = 0;
var i = nextIndex;
while (i < input.Length && cmp(input[i], symbol))
{
count++;
i++;
}
return count;
}
答案 3 :(得分:0)
第一种解决方案不处理单个字符。例如 - '嗨!'不管用。我使用了完全不同的方法,使用'insert()'函数添加到位。这将照顾一切,无论总的“相同”字符是&gt; 10或> 100或= 1。
#include<iostream>
#include<algorithm>
using namespace std;
int main(){
string name = "Hello Buddy!!";
int start = 0;
char distinct = name[0];
for(int i=1;i<name.length()+1;){
if(distinct!=name[i]){
string s = to_string(i-start);
name.insert(start+1,s);
name.erase(name.begin() + start + 1 + s.length(),name.begin() + s.length() + i);
i=start+s.length()+1;
start=i;
distinct=name[start];
continue;
}
i++;
}
cout<<name;
}
如果您发现任何错误,建议我。
答案 4 :(得分:0)
O(n),就地RLE,我想不出更好。它不会放置一个数字,如果chars occurence只是1.如果角色出现11次,也会放置a9a2。
void RLE(char *str) {
int len = strlen(str);
int count = 1, j = 0;
for (int i = 0; i < len; i++){
if (str[i] == str[i + 1])
count++;
else {
int times = count / 9;
int rem = count % 9;
for (int k = 0; k < times; k++) {
str[j++] = str[i];
_itoa(9, &str[j++], 10);
count = count - 9;
}
if (count > 1) {
str[j++] = str[i];
_itoa(rem, &str[j++], 10);
count = 1;
}
else
str[j++] = str[i];
}
}
cout << str;
}
I / P =&gt; aaabcdeeeefghijklaaaaa
O / P =&gt; a3bcde4fghijkla5
答案 5 :(得分:0)
Inplace solution using c++ ( assumes length of encoding string is not more than actual string length):
#include <bits/stdc++.h>
#include<stdlib.h>
using namespace std;
void replacePattern(char *str)
{
int len = strlen(str);
if (len == 0)
return;
int i = 1, j = 1;
int count;
// for each character
while (str[j])
{
count = 1;
while (str[j] == str[j-1])
{
j = j + 1;
count++;
}
while(count > 0) {
int rem = count%10;
str[i++] = to_string(rem)[0];
count = count/10;
}
// copy character at current position j
// to position i and increment i and j
if (str[j])
str[i++] = str[j++];
}
// add a null character to terminate string
if(str[len-1] != str[len-2]) {
str[i] = '1';
i++;
}
str[i] = '\0';
}
// Driver code
int main()
{
char str[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabccccc";
replacePattern(str);
cout << str;
return 0;
}