给定一组字符,使用原地算法将其压缩。
压缩后的长度必须始终小于或等于原数组长度。
数组的每个元素应该是长度为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”替代。
注意每个数字在数组中都有它自己的位置。
链接:https://leetcode-cn.com/problems/string-compression
思路
设置 i 为遍历指针
设置 j 为写入指针
当 chars[i] == chars[j] 时,说明字符一样,cnt++ 计数增加
当不等时,需要
41. j++ 把写入指针移到之后一个位置,准备写入数字
42. 写入数字,注意考虑次数超过 1 位数的情况
43. chars[j] = chars[i] 将填入数字之后的下一位等于下一个要压缩的字符
44. 通过一些技巧处理,可以将逻辑写在一个循环里
返回写入指针最后的位置 return j;
链接:https://leetcode-cn.com/problems/string-compression/solution/443-by-ikaruga/
class Solution { public int compress(char[] chars) { int j=0,cnt=0; if(chars.length==0) return 0 ; for(int i =1 ;i<=chars.length;i++) { cnt++; if(i==chars.length||chars[i]!=chars[j]) { j++; if(cnt!=1) { for(char c:String.valueOf(cnt).toCharArray()) { chars[j++] =c ; } } if(i ==chars.length) break; //将填入数字之后的下一位等于下一个要压缩的字符 chars[j]=chars[i]; cnt = 0; } } for(int i=0;i<j;i++) { System.out.println(chars[i]); } return j ; } }
C语言版本待查看先贴上别人的代码
<C语言版:> int compress(char* chars, int charsSize) { int cur = 0; for(int i = 0, j = 0; i < charsSize; j = i) { while(i < charsSize && chars[i] == chars[j]) { i++; } chars[cur++] = chars[j]; if(i - j == 1) continue; char s[1000]; sprintf(s, "%d", i - j); for(int t = 0; t < strlen(s); t++) { chars[cur++] = s[t]; } } return cur; } 链接:https://leetcode-cn.com/problems/string-compression/solution/ccti-jie-