替换空格
//替换空格: 请实现一个函数,把字符串 s 中的每个空格替换成"%20"
public String replaceSpace(String s) {
int newLen = 0;
final char[] oldChars = s.toCharArray();
for (char ch : oldChars) {
newLen = (ch == ' ' ) ? newLen + 3 : newLen + 1;
}
if (newLen == oldChars.length) return s;
char[] newChars = new char[newLen];
int nIdx = newChars.length - 1;
for (int i = oldChars.length - 1; i >= 0; i--) {
if (oldChars[i] == ' ') {
newChars[nIdx--] = '0';
newChars[nIdx--] = '2';
newChars[nIdx--] = '%';
continue;
}
newChars[nIdx--] = oldChars[i];
}
return new String(newChars);
}
反转字符串
/*编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 char[] 的形式给出。
不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 $O(1)$ 的额外空间解决这一问题。*/
public void reverseString(char[] s) {
if (s == null || s.length < 2) return;
int left = 0, right = s.length - 1;
while (left < right) {
char temp = s[left];
s[left] = s[right];
s[right] = temp;
left++;
right--;
}
}
/***
* @Description 每遍历2k个字符, 反转前k个字符. 剩余字符小于k个, 都反转, 剩余字符大于k个,小于2k个, 只反转前k个
* @Title reverseStr
* @Date 2022/7/7
*/
public String reverseStr(String s, int k) {
final char[] chars = s.toCharArray();
for (int i = 0; i < chars.length; i += 2 * k) {
// 剩余字符大于k个,小于2k个, 只反转前k个
if (i + k <= chars.length) {
reverse(chars, i, i + k - 1);
continue;
}
//剩余字符不到k个的
reverse(chars, i, chars.length - 1);
}
return new String(chars);
}
public void reverse(char[] chs, int start, int end) {
for (; start < end; start++, end--) {
char temp = chs[start];
chs[start] = chs[end];
chs[end] = temp;
}
}
public static void main(String[] args) {
final ReverseString reverseString = new ReverseString();
/*final char[] chars = {'a', 'b', 'c', 'd', 'e', 'f'};
reverseString.reverseString(chars);
System.out.println(Arrays.toString(chars));*/
final String str = reverseString.reverseStr("abcdefg" ,8);
System.out.println(str);
}
实现strstr()
方法一
/**
* @Classname StrStr
* @Description 实现 strStr() : KMP(两种) or 滑动窗口
* 给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回 -1。
* @Date 2022/7/14 11:03
*/
public class StrStr {
// KMP 方法一: 下标不减1
public int strStr(String haystack, String needle) {
if (needle == null || needle.length() == 0) return 0;
final int[] next = getNext(needle);
int j = 0;
for (int i = 0; i < haystack.length(); i++) {
while (j > 0 && needle.charAt(j) != haystack.charAt(i)) {
j = next[j - 1];
}
if (needle.charAt(j) == haystack.charAt(i)) {
j++;
}
if (j == needle.length()) {
return i - needle.length() + 1;
}
}
return -1;
}
private int[] getNext(String needle) {
final int[] next = new int[needle.length()];
int j = 0;
next[j] = 0;
for (int i = 1; i < needle.length(); i++) {
while (j > 0 && needle.charAt(i) != needle.charAt(j)) {
j = next[j - 1];
}
if(needle.charAt(i) == needle.charAt(j)){
j++;
}
next[i] = j;
}
return next;
}
public static void main(String[] args) {
final StrStr strStr = new StrStr();
final int i = strStr.strStr("aaaaab", "ab");
System.out.println(i);
}
}
方法二
// KMP 方法二: 下标-1
public int strStr(String haystack, String needle) {
if (needle == null || needle.length() == 0) return 0;
final int[] next = getNext(needle);
int j = -1;
for (int i = 0; i < haystack.length(); i++) {
while (j >= 0 && needle.charAt(j + 1) != haystack.charAt(i)) {
j = next[j];
}
if (needle.charAt(j + 1) == haystack.charAt(i)) {
j++;
}
if (j == needle.length() - 1) {
return i - needle.length() + 1;
}
}
return -1;
}
private int[] getNext(String needle) {
final int[] next = new int[needle.length()];
int j = -1;
next[0] = j;
for (int i = 1; i < needle.length(); i++) {
while (j >= 0 && needle.charAt(i) != needle.charAt(j + 1)) {
j = next[j];
}
if (needle.charAt(i) == needle.charAt(j + 1)) {
j++;
}
next[i] = j;
}
return next;
}
重复子字符串
public boolean repeatedSubstringPattern(String s) {
if (s.equals("")) return false;
int len = s.length();
s = " " + s;
char[] chars = s.toCharArray();
int[] next = new int[len + 1];
for (int i = 2, j = 0; i <= len; i++) {
while (j > 0 && chars[i] != chars[j + 1]) j = next[j];
if (chars[i] == chars[j + 1]) j++;
next[i] = j;
}
return next[len] > 0 && (len % (len - next[len]) == 0);
}