题意: 压缩字符串,如:“aabbccc"压缩为"a2b2c3”,如果压缩后的字符串长度大于等于原字符串,则返回原来的字符串。
解法(双指针法)
思路:
- 建立p1,p2双指针:p1指向同字符子串的头部,p2用来扫描原字符串,找子串尾部
- p1与p2之间的子串即为同字符子串,p2-p1为子串长度
- 把p1指向的字符和子串长度追加到StringBuffer中
- 最后判断以下StringBuffer和原字符串长度
class Solution {
public String compressString(String S) {
// p1指向字符重复子串的头部
int p1 = 0;
// p2扫描出字符重复子串的范围
int p2 = 0;
StringBuffer buffer = new StringBuffer();
while (p2 < S.length()) {
while (p2 < S.length() && S.charAt(p1) == S.charAt(p2)) p2++;
buffer.append(S.charAt(p1)).append(p2 - p1);
p1 = p2;
}
if(buffer.length() >= S.length()) {
return S;
} else return buffer.toString();
}
}
优化
思路: 遍历字符串时把字符串转为char[] c = S.toCharArray(),再遍历char数组效率更高,通过s.charAt(i)方法索引多了方法栈和越界检查的消耗
class Solution {
public String compressString(String S) {
// p1指向字符重复子串的头部
int p1 = 0;
// p2扫描出字符重复子串的范围
int p2 = 0;
StringBuffer buffer = new StringBuffer();
char[] str = S.toCharArray();
while (p2 < str.length) {
while (p2 < str.length && str[p1] == str[p2]) p2++;
buffer.append(str[p1]).append(p2 - p1);
p1 = p2;
}
return buffer.length() >= S.length() ? S : buffer.toString();
}
}
收获:
-
p1指向子串头部,p2指向尾部后一位,则p2-p1即为子串长度
-
以后要遍历字符串的时候尽量把字符串转为字符数组,效率要快一倍
-
以后把
if ... else ...
语句替换成三目运算符? :
逼格更高,大佬们都这么做的