0. 一些语法
String.copyValueOf(ch); //字符串数组转字符串
str.length; //字符串数组长度
str.toCharArray(); //字符串转为字符串数组
s.length(); //字符串长度
int[] res = new int[n]; //创建大小为n的整型数组
StringBuilder sb = new StringBuilder(); //创建StringBuilder对象, 可以对字符串进行动态删减
sb.toString(); //StringBuilder对象转换为字符串
1. 反转字符串 : 双指针
class Solution {
public void reverseString(char[] s) {
int left = 0;
int right = s.length - 1;
char temp;
while (left < right) { //交换就行
temp = s[left];
s[left] = s[right];
s[right] = temp;
left ++;
right --;
}
}
}
2. 反转字符串Ⅱ: 双指针
给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。
class Solution {
public String reverseStr(String s, int k) {
char[] ch = s.toCharArray();
for (int i = 0; i < ch.length; i += 2 * k) {
int start = i;
int end = Math.min(ch.length - 1, start + k -1); //根据end的取值来判断后面是否还够k个
while (start < end) { //反转操作
char temp = ch[start];
ch[start] = ch[end];
ch[end] = temp;
start ++;
end --;
}
}
return String.copyValueOf(ch);
}
}
3. 替换空格:双指针
先在末尾加上空格,然后连接字符串,接着从后往前遍历,遇到空格就将right指向的三个值分别赋值为%20,否则就left赋值给right
class Solution {
public String replaceSpace(String s) {
if (s == null || s.length() ==0) {
return s;
}
StringBuilder sb = new StringBuilder();
//扩容数组
for (int i = 0; i < s.length(); i ++) {
if (s.charAt(i) == ' ') {
sb.append(" ");
}
}
//没有空格
if (sb.length() == 0) {
return s;
}
//有空格的话将两个字符串连接起来
int left = s.length() - 1; //左指针指向原始字符串最后一个位置
s += sb.toString();
int right = s.length() - 1; //右指针指向叠加后字符串的最后一个位置
char[] ch = s.toCharArray();
while (left >= 0) {
//遇到空格就将right对应的前三个值直接换掉
if (ch[left] == ' ') {
ch[right --] = '0';
ch[right --] = '2';
ch[right] = '%';
}
else{
ch[right] = ch[left]; //没有遇到空格就直接替换
}
left --;
right --;
}
return String.copyValueOf(ch);
}
}
4. 反转字符串里面的单词
需要注意的是如果开始有空格,split会将它转换为""
class Solution {
public String reverseWords(String s) {
ArrayList<String> list = new ArrayList<>();
String[] string = s.split(" "); //按照空格分割字符串
//需要删除"",使用list较为方便
for(String st : string) {
if(st != "") {
list.add(st);
}
}
String[] str = list.toArray(new String[list.size()]); //列表转换为数组
int left = 0;
int right = str.length - 1;
while(left <= right) {
String temp = str[left];
str[left] = str[right];
str[right] = temp;
left++;
right--;
}
//数组转换为字符串
String res = "";
for(int i = 0; i < str.length - 1; i++) {
res = res + str[i] + " ";
}
return res + str[str.length - 1];
}
}
5. 向左旋转字符串
//1. 暴力解法 会超时
class Solution {
public String reverseLeftWords(String s, int n) {
int len = s.length();
if(n <= 0 || n > len) {
return s;
}
StringBuilder sb = new StringBuilder();
String res = s;
//把前面的删除的同时在后面加上该字符
for(int i = 0; i < len; i++) {
if(i < n) {
sb.append(s.charAt(i));
res = deleteStr(res);
//System.out.println(res);
}
}
return res += sb.toString();
}
//用于删除字符串的第一个字符
private String deleteStr(String str) {
char[] ch= str.toCharArray();
char[] temp = new char[ch.length - 1];
for(int i = 0; i < ch.length - 1; i++) {
temp[i] = ch[i + 1];
}
return String.copyValueOf(temp);
}
}
// 2. 一下子全部删除前面的n个字符,再去后面添加
class Solution {
public String reverseLeftWords(String s, int n) {
int len = s.length();
if(n <= 0 || n > len) {
return s;
}
StringBuilder sb = new StringBuilder();
String res = s;
res = deleteStr(res, n);
//在后面加上该字符
for(int i = 0; i < len; i++) {
if(i < n) {
sb.append(s.charAt(i));
}
}
return res += sb.toString();
}
//用于删除字符串的前n个字符
private String deleteStr(String str, int n) {
char[] ch= str.toCharArray();
char[] temp = new char[ch.length - n];
for(int i = 0; i < ch.length - n; i++) {
temp[i] = ch[i + n];
}
return String.copyValueOf(temp);
}
}
//3. 先反转前面的,再反转后面的,最后整体再反转一次
class Solution {
public String reverseLeftWords(String s, int n) {
int len = s.length();
if(n <= 0 || n > len) {
return s;
}
StringBuilder sb = new StringBuilder();
String temp = reverse(s, 0, n-1);
sb.append(reverse(temp, n, len - 1));
return reverse(sb.toString(), 0, len - 1);
}
private String reverse(String str, int start, int end) {
char[] ch = str.toCharArray();
while(start <= end) {
char temp = ch[start];
ch[start] = ch[end];
ch[end] = temp;
start++;
end--;
}
return String.copyValueOf(ch);
}
}
6. 找到子串匹配的下标
class Solution {
public int strStr(String haystack, String needle) {
char[] hay = haystack.toCharArray();
int haylen = hay.length;
char[] nee = needle.toCharArray();
int neelen = nee.length;
//不是它的一部分就返回-1
if(haylen < neelen) {
return -1;
}
List<Integer> list = new ArrayList<>();
for(int i = 0; i < haylen - 1; i++) {
for(int j = 0; j < neelen; j++) {
if(hay[i] == nee[j]) {
list.add(i);
i++;
}
else {
break;
}
}
}
if(list.size() < neelen) {
return -1;
}
else return list.get(0);
}
}
7. 判断一个字符串是否可以由它的子串多次重复构成
class Solution {
public boolean repeatedSubstringPattern(String s) {
int len = s.length();
if(len == 1) return false;
s = " " + s;
char[] ch = s.toCharArray(); //转换为数组
int[] next = new int[len + 1]; //next数组
//获取next数组
for(int j = 0, i = 2; i <= len; i++) {
while(j > 0 && ch[j + 1] != ch[i]) j = next[j];
if(ch[j+1] == ch[i]) j++;
next[i] = j;
}
//next只要有值就证明之前已经有子串了,不然的话next将会是一直为零
if(next[len] > 0 && len % (len - next[len]) == 0) {
return true; //长度是子串的倍数
}
return false;
}
}