Given an array of characters, compress it in-place.
The length after compression must always be smaller than or equal to the original array.
Every element of the array should be a character (not int) of length 1.
After you are done modifying the input array in-place, return the new length of the array.
Follow up:
Could you solve it using only O(1) extra space?
Example 1:
Input: ["a","a","b","b","c","c","c"] Output: Return 6, and the first 6 characters of the input array should be: ["a","2","b","2","c","3"] Explanation: "aa" is replaced by "a2". "bb" is replaced by "b2". "ccc" is replaced by "c3".
Example 2:
Input: ["a"] Output: Return 1, and the first 1 characters of the input array should be: ["a"] Explanation: Nothing is replaced.
Example 3:
Input: ["a","b","b","b","b","b","b","b","b","b","b","b","b"] Output: Return 4, and the first 4 characters of the input array should be: ["a","b","1","2"]. Explanation: Since the character "a" does not repeat, it is not compressed. "bbbbbbbbbbbb" is replaced by "b12". Notice each digit has it's own entry in the array.
Note:
- All characters have an ASCII value in
[35, 126]
. 1 <= len(chars) <= 1000
.
给定一组字符,使用原地算法将其压缩。
压缩后的长度必须始终小于或等于原数组长度。
数组的每个元素应该是长度为1 的字符(不是 int 整数类型)。
在完成原地修改输入数组后,返回数组的新长度。
进阶:
你能否仅使用O(1) 空间解决问题?
示例 1:
输入: ["a","a","b","b","c","c","c"] 输出: 返回6,输入数组的前6个字符应该是:["a","2","b","2","c","3"] 说明: "aa"被"a2"替代。"bb"被"b2"替代。"ccc"被"c3"替代。
示例 2:
输入: ["a"] 输出: 返回1,输入数组的前1个字符应该是:["a"] 说明: 没有任何字符串被替代。
示例 3:
输入: ["a","b","b","b","b","b","b","b","b","b","b","b","b"] 输出: 返回4,输入数组的前4个字符应该是:["a","b","1","2"]。 说明: 由于字符"a"不重复,所以不会被压缩。"bbbbbbbbbbbb"被“b12”替代。 注意每个数字在数组中都有它自己的位置。
注意:
- 所有字符都有一个ASCII值在
[35, 126]
区间内。 1 <= len(chars) <= 1000
。
题解:首先这道题目,需要用o(1)的空间复杂度来完成,那么这时候就要考虑用多个指针来满足条件,通过调用多个指针,让不同的指针指向不同的位置,即可完成。
public static int compress(char[] chars)
{
if(chars.length == 0)
return 0;
int m = 0,i = 0,j;
while(i < chars.length)
{
j = i;
chars[m++] = chars[i];
int k = 0;
while(j < chars.length && chars[i] == chars[j])
{
k++;
j++;
}
StringBuilder sb = new StringBuilder();
if(k != 1)
{
while(k != 0)
{
sb.append((char)(k % 10 + 48));
k /= 10;
}
}
sb.reverse();
for(char c : sb.toString().toCharArray())
chars[m++] = c;
i = j;
}
return m;
}
首先,需要三个指针,分别为i,j和m。其中,i指向原来数组中第一次出现某个元素的位置,而j则表示数组下标,会随着依次搜寻往后走;而m则用来记录某一个元素在数组中出现的次数。当循环条件为j不大于数组长度且第一次出现某个元素与之后的元素不一样,那么就将其结束循环,然后用一个stringbuilder来进行求个数,并反转。这里需要特别注意的是,在求元素出现个数时,要特别当心,当元素出现的次数只有1次时,不需要将其写入数组中。