【11.19】替换所有的问号
分析:
***第一种方法:***可以建立一个空间为26的数组,里边存放26个不同的小写字母,遍历一遍字符串,将已存在于数组的字母设置为-1,到时候再遍历一次字符串,将问号换成字符数组里边value非-1的字母即可。
另外,其实普通的整型数组也可,就是再对应的时候稍微要转换一下,不过省掉了将字母存入数组的操作。
难点在于:如何让字符串种的字符以O(1)的时间复杂度对应到数组?
答:用ASCII码。小写a对应的ASCII码为97,z对应的是122,将其减去97则对应的就是字符数组下标
顺便复习一下,大写A对应的ASCII码为65,Z对应的是90。
***第二种方法:***只需要判断当前位置的?的取值不和前一个值以及后一个值相同即可。
//执行用时:2 ms, 在所有 Java 提交中击败了47.87% 的用户
//内存消耗:38.5 MB, 在所有 Java 提交中击败了41.83% 的用户
class Solution {
public String modifyString(String s) {
char[] chars = s.toCharArray();
for (int i = 0; i < chars.length; i++) {
if (chars[i] == '?') {
//前面一个字符 如果当前是第0个的话 字符就为‘ ’
char ahead = i == 0 ? ' ' : chars[i - 1];
//后面一个字符 如果当前是最后一个的话 字符就为‘ ’
char behind = i == chars.length - 1 ? ' ' : chars[i + 1];
//从a开始比较 如果等于前面或者后面的话 就+1
char temp = 'a';
while (temp == ahead || temp == behind ) {
temp++;
}
//找到目标字符后 做替换
chars[i] = temp;
}
}
return new String(chars);
}
}
作者:JayceonDu
链接:https://leetcode-cn.com/problems/replace-all-s-to-avoid-consecutive-repeating-characters/solution/jian-dan-de-ji-xing-dai-ma-by-jayceondu/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
【11.20】重复的子字符串
分析:这题标的easy我是万万没想到的…看题解的方法是用的一个数学证明
假如说给出的字符串是由某子字符串重复两次以上得到,那么就判定为true,否则为false
假如给定字符串为s,子字符串为x,重复次数为n。构造新字符串t = 2s(即两个s相加),由于s = nx,则t = 2nx。对t进行去头掐尾处理,这样的话,两处的子串被破坏掉,那么剩下的重复次数应该为2n-2,若t中包含s,那么由2n-2>=n,则n>=2。这样就满足了以上预设,判定为true。
(长话短说:假如t去头掐尾之后,s还是其子字符串,那么就为true)
难点:如何实现去头掐尾?
A1:从位置1开始查询,并希望查询结果不为位置n即可;
//执行用时:117 ms, 在所有 Java 提交中击败了14.87% 的用户
//内存消耗:38.9 MB, 在所有 Java 提交中击败了96.90% 的用户
class Solution {
public boolean repeatedSubstringPattern(String s) {
return (s + s).indexOf(s, 1) != s.length();
}
}
//执行用时:95 ms, 在所有 Java 提交中击败了48.71% 的用户
//内存消耗:39 MB, 在所有 Java 提交中击败了89.62% 的用户
class Solution{
public boolean repeatedSubstringPattern(String s){
String str = s+s;
return str.substring(1,str.length()-1).contains(s);
}
}
【11.21】上升下降字符串
分析:题意大概就是首先按照字符大小增序排列,然后降序,然后反复。
方法1:桶排序。长度为26的数组表示26个桶,每个桶里放一个字母,遍历一遍字符串,将字母放进对应的桶中,然后按照顺序遍历桶输出第一遍,然后逆序输出一遍,反复即可,(每输出一次,计数器-1)直到所有桶中的计数器为0.
//执行用时:4 ms, 在所有 Java 提交中击败了45.10% 的用户
//内存消耗:38.3 MB, 在所有 Java 提交中击败了92.24% 的用户
class Solution {
int[] h = new int[26];
public String sortString(String s) {
for (int i = 0; i < s.length(); ++i) {
++h[s.charAt(i) - 'a'];
}
StringBuffer ret = new StringBuffer();
while (true) {
if (!haveChar()) {
break;
}
for (int i = 0; i < 26; ++i) {
appendChar(ret, i);
}
for (int i = 25; i >= 0; --i) {
appendChar(ret, i);
}
}
return ret.toString();
}
public void appendChar(StringBuffer ret, int p) {
if (h[p] > 0) {
--h[p];
ret.append((char) (p + 'a'));
}
}
public boolean haveChar() {
for (int i = 0; i < 26; ++i) {
if (h[i] != 0) {
return true;
}
}
return false;
}
}
【11.22】字符串压缩
分析:设置一个指针指向字母,相同则计数器+1,碰到不同的字母则将当前计数器的值放在结果字符串后,然后计数器清零。
class Solution {
public String compressString(String S) {
if (S.length() == 0) { // 空串处理
return S;
}
StringBuffer ans = new StringBuffer();
int cnt = 1;
char ch = S.charAt(0);
for (int i = 1; i < S.length(); ++i) {
if (ch == S.charAt(i)) {
cnt++;
} else {
ans.append(ch);
ans.append(cnt);
ch = S.charAt(i);
cnt = 1;
}
}
ans.append(ch);
ans.append(cnt);
return ans.length() >= S.length() ? S : ans.toString();
}
}