Google – Compress String II
假设一个文件压缩后的表示是:
#3, #5, #6, 2 5, #8
#d表示单个数字d
两个数字"i j"表示取前i个数字,组长度为j的字符串。
比如 "#3" 就表示3
"2 5"表示前面两个数字,就是56,组成长度为5的字符串,就是56565
所以上面的例子,解压缩之后应该是: 3 5 6 5 6 5 6 5 8
要求是写一个压缩算法,把string按要求压缩。
比如 2 3 4 5 2 3 4 5 1, 返回#2, #3, #4, #5, 4 4, #1
[Solution]
一边扫描一边用hashtable 记录window size为2的pattern, map到这个Pattern所有出现过的位置,如果发现重复的,就开始往后match。
面经上写着window size为3,并且map到最后出现的位置,应该是不对。首先window size为3就不知道是为什么。其次map到最后出现的位置也有问题,比如
3 5 6 1 4 5 6 1 5 5 6 1 4 5 6 1 5
第二个5 6 1后面是5,并不能match第一个5 6 1后面的4。要直到第三个5 6 1才能match前面8个字符。但是如果5 6 1map到最后出现的位置的话,是无法继续match下去的。
Read full article from Google – Compress String II
假设一个文件压缩后的表示是:
#3, #5, #6, 2 5, #8
#d表示单个数字d
两个数字"i j"表示取前i个数字,组长度为j的字符串。
比如 "#3" 就表示3
"2 5"表示前面两个数字,就是56,组成长度为5的字符串,就是56565
所以上面的例子,解压缩之后应该是: 3 5 6 5 6 5 6 5 8
要求是写一个压缩算法,把string按要求压缩。
比如 2 3 4 5 2 3 4 5 1, 返回#2, #3, #4, #5, 4 4, #1
[Solution]
一边扫描一边用hashtable 记录window size为2的pattern, map到这个Pattern所有出现过的位置,如果发现重复的,就开始往后match。
面经上写着window size为3,并且map到最后出现的位置,应该是不对。首先window size为3就不知道是为什么。其次map到最后出现的位置也有问题,比如
3 5 6 1 4 5 6 1 5 5 6 1 4 5 6 1 5
第二个5 6 1后面是5,并不能match第一个5 6 1后面的4。要直到第三个5 6 1才能match前面8个字符。但是如果5 6 1map到最后出现的位置的话,是无法继续match下去的。
public String compress(String s) { if (s == null || s.isEmpty()) { return s; } Map<String, List<Integer>> map = new HashMap<>(); StringBuilder sb = new StringBuilder(); sb.append("#" + s.charAt(0)); for (int i = 1; i < s.length(); i++) { String pattern = String.format("%c%c", s.charAt(i - 1), s.charAt(i)); if (!map.containsKey(pattern)) { map.put(pattern, new ArrayList<>()); sb.append(" ").append("#" + s.charAt(i)); } else { boolean found = false; for (int j : map.get(pattern)) { int l = j + 1; int r = i + 1; while (r < s.length() && s.charAt(l) == s.charAt(r)) { l++; r++; } if (l < i - 1) { continue; } else { int prevNum = i - j; int len = r - i + 1; sb.delete(sb.length() - 3, sb.length()); sb.append(" ").append(prevNum + " " + len); found = true; i = r - 1; break; } } if (!found) { sb.append(" ").append("#" + s.charAt(i)); } } map.get(pattern).add(i); } return sb.toString(); }