压缩字符串的思路探讨与源码
压缩字符串的题目如下图,该题属于双指针类型和字符串类型的题目,主要考察对于双指针搜索方法的使用和字符串结构的理解。本文的题目作者想到2种方法,分别是双指针方法和三指针方法,其中双指针方法使用Java进行编写,而三指针方法使用Python进行编写,当然这可能不是最优的解法,还希望各位大佬给出更快的算法。
本人认为该题目可以使用双指针方法的思路进行解决,首先计算字符串数组的长度,并初始化左右指针的位置,开始遍历循环,判断指针是否位于字符串的末尾,或读指针指向的字符不同于下一个字符时,就可以认为读指针read位于某一段连续相同子串的最右侧。然后判断区间长度是否大于1,如果是就把左边的下标赋值,并进行内部迭代循环,按此思路进行遍历,直到循环结束并返回结果。那么按照这个思路我们的Java代码如下:
#喷火龙与水箭龟
class Solution {
public int compress(char[] chars) {
int numLen = chars.length;
int aex = 0;
int bex = 0;
for (int read = 0; read < numLen; read++) {
if (read == numLen - 1 || chars[read] != chars[read + 1]) {
chars[aex++] = chars[read];
int num = read - bex + 1;
if (num > 1) {
int ind = aex;
while (num > 0) {
chars[aex++] = (char) (num % 10 + '0');
num = num / 10;
}
reverse(chars, ind, aex - 1);
}
bex = read + 1;
}
}
return aex;
}
public void reverse(char[] chars, int bex, int right) {
while (bex < right) {
char temp = chars[bex];
chars[bex] = chars[right];
chars[right] = temp;
bex = bex + 1;
right = right - 1;
}
}
}
显然,我们的双指针方法的效果不错,还可以用三指针方法进行解决。首先计算数组长度,并初始化下标位置,判断下标是否小于数组长度,如果是则进入循环,将下标赋值给另一个下标,判断当前下标是否小于数组长度并且当前元素是否等于之前的下标元素,如果是就进入循环并把当前新的下标加1,子循环结束以后,把之前下标的元素赋值给第三个指针的元素。然后判断左右指针的间距是否大于1,如果是就进行子循环遍历,将遍历的结果赋值给第三个指针的元素并把第三个指针的下标加1,按这个思路直到循环遍历结束并返回结果。所以按照这个思路就可以解决,下面是Python代码:
#喷火龙与水箭龟
class Solution:
def compress(self, chars: List[str]) -> int:
numLen = len(chars)
ir = 0
ind = 0
while ir < numLen:
jr = ir
while jr < numLen and chars[jr] == chars[ir]:
jr = jr + 1
chars[ind] = chars[ir]
ind = ind + 1
if((jr - ir) > 1):
for kr in str(jr-ir):
chars[ind] = kr
ind = ind + 1
ir = jr
return ind
从结果来说Java版本的双指针方法的效率不错,而Python版本的三指针方法的速度比较一般,但应该是有更多的方法可以进一步提速的,希望朋友们能够多多指教,非常感谢。