You are given a string with lower case letters only. Compress it by putting the count of the letter after it. If the letter appears once,
Example:
compress function:
input = aaaabbc output = a4b2c
decompress function:
input = a2bc3 output = aabccc
1 public class Solution { 2 public String compress(String input) { 3 int startIndex = 0; 4 StringBuilder output = new StringBuilder(); 5 while (startIndex < input.length()) { 6 int nextIndex = findNextIndex(input, startIndex); 7 int length = nextIndex - startIndex; 8 output.append(input.charAt(startIndex)); 9 if (length != 1) { 10 output.append(length); 11 } 12 startIndex = nextIndex; 13 } 14 return output.toString(); 15 } 16 17 // a4b2c 18 public String decompress(String input) { 19 int startIndex = 0; 20 StringBuilder output = new StringBuilder(); 21 while (startIndex < input.length()) { 22 char ch = input.charAt(startIndex); 23 int numberEndIndex = findNumberEndIndex(input, startIndex); 24 if (numberEndIndex - startIndex == 1) { 25 repeatLetters(output, 1, ch); 26 } else { 27 int count = Integer.parseInt(input.substring(startIndex + 1, numberEndIndex)); 28 repeatLetters(output, count, ch); 29 } 30 startIndex = numberEndIndex; 31 } 32 return output.toString(); 33 } 34 35 private int findNumberEndIndex(String input, int startIndex) { 36 int endIndex = startIndex + 1; 37 while (endIndex < input.length() && isNumber(input.charAt(endIndex))) { 38 endIndex++; 39 } 40 return endIndex; 41 } 42 43 private boolean isNumber(char ch) { 44 return ch >= '0' && ch <= '9'; 45 } 46 47 private void repeatLetters(StringBuilder output, int count, char ch) { 48 while (count >= 1) { 49 output.append(ch); 50 count--; 51 } 52 } 53 54 private int findNextIndex(String input, int startIndex) { 55 int endIndex = startIndex + 1; 56 while (endIndex < input.length() && input.charAt(endIndex) == input.charAt(startIndex)) { 57 endIndex++; 58 } 59 return endIndex; 60 } 61 }
follow-up
如果字符串里有数字,比如44443333aaabbc, 它会被转成 /44/34a3b2c
其实对于这种情况的处理还是比较简单的,我们只需要知道当前letter是否是数字,如果是数字,我们就在前面加‘/’。对于decompress, 我们也需要判断当前是否是‘/’,如果是,表明第一个是数字,数字后面的到下一个‘/’之前都是个数。
1 public class Solution { 2 public String compress(String input) { 3 int startIndex = 0; 4 StringBuilder output = new StringBuilder(); 5 while (startIndex < input.length()) { 6 int nextIndex = findNextIndex(input, startIndex); 7 int length = nextIndex - startIndex; 8 char letter = input.charAt(startIndex); 9 if (isNumber(letter)) { 10 output.append('/'); 11 } 12 output.append(letter); 13 if (length != 1) { 14 output.append(length); 15 } 16 startIndex = nextIndex; 17 } 18 return output.toString(); 19 } 20 21 // /44/35b11a4c 22 // b11a4c/44/35 23 public String decompress(String input) { 24 int startIndex = 0; 25 StringBuilder output = new StringBuilder(); 26 while (startIndex < input.length()) { 27 char ch = input.charAt(startIndex); 28 if (ch == '/') { 29 startIndex++; 30 ch = input.charAt(startIndex); 31 } 32 int numberEndIndex = findNumberEndIndex(input, startIndex); 33 if (numberEndIndex - startIndex == 1) { 34 repeatLetters(output, 1, ch); 35 } else { 36 int count = Integer.parseInt(input.substring(startIndex + 1, numberEndIndex)); 37 repeatLetters(output, count, ch); 38 } 39 startIndex = numberEndIndex; 40 } 41 return output.toString(); 42 } 43 44 private int findNumberEndIndex(String input, int startIndex) { 45 int endIndex = startIndex + 1; 46 while (endIndex < input.length() && isNumber(input.charAt(endIndex))) { 47 endIndex++; 48 } 49 return endIndex; 50 } 51 52 private boolean isNumber(char ch) { 53 return ch >= '0' && ch <= '9'; 54 } 55 56 private void repeatLetters(StringBuilder output, int count, char ch) { 57 while (count >= 1) { 58 output.append(ch); 59 count--; 60 } 61 } 62 63 private int findNextIndex(String input, int startIndex) { 64 int endIndex = startIndex + 1; 65 while (endIndex < input.length() && input.charAt(endIndex) == input.charAt(startIndex)) { 66 endIndex++; 67 } 68 return endIndex; 69 } 70 }