for (int i = 0, j = s.length - 1; i <= j; i++, j--) {
char temp = s[i];
s[i] = s[j];
s[j] = temp;
}
public String reverseStr(String s, int k) {
int len = s.length();
char[] charS = s.toCharArray();
int start,end;
for (int i = 0; i < charS.length; i+=2*k) {
start = i;
if(i + k > len){
end = charS.length-1;
}else {
end = i + k-1;
}
reverse(charS,start,end);
}
return new String(charS);
}
public char[] reverse(char[] s,int i,int j){
for (;i <= j; i++, j--) {
char temp = s[i];
s[i] = s[j];
s[j] = temp;
}
return s;
}
/**
* 剑指Offer 05.替换空格
*
* @param s
* @return
*/
public String replaceString(String s) {
if(s == null ) return null;
StringBuilder sb = new StringBuilder();
char[] chars = s.toCharArray();
for (int i = 0; i < chars.length; i++) {
if(chars[i] == 32){
sb.append("%20");
}else{
sb.append(chars[i]);
}
}
return sb.toString();
}
方法1:
/**
* 暴力法,时间复杂度太高
*
* @param s
* @return
*/
public String reverseWords2(String s) {
s = s.trim(); //去除首尾空格
List<StringBuilder> list = new ArrayList<>();
char[] chars = s.toCharArray();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < chars.length; i++) {
if (chars[i] == 32) {
if (!sb.toString().equals("")) {
list.add(sb);
}
sb = new StringBuilder("");
} else {
sb.append(chars[i]);
}
}
list.add(sb);
for (int i = 0, j = list.size() - 1; i < j; i++, j--) {
StringBuilder temp = list.get(i);
list.set(i, list.get(j));
list.set(j, temp);
}
String res = "";
for (int i = 0; i < list.size(); i++) {
res += list.get(i).toString() + " ";
}
return res.trim(); //末尾多了一个空格
}
方法2:
public String reverseWords(String s) {
//首先去除多余的空格
//再反转整个字符串
//最后单个单词进行反转
StringBuilder sb = removeSpace(s);
char[] chars = reverseString(sb.toString().toCharArray(), 0, sb.length() - 1);
reverseEachWord(chars);
return new String(chars);
}
/**
* 反转每个单词
*
* @param chars
*/
public void reverseEachWord(char[] chars) {
int start = 0, end = 1;
while (start < chars.length){
while (end < chars.length && chars[end] != ' ') {
end++;
}
reverseString(chars, start, end-1);
start = end + 1;
end = start + 1;
}
}
/**
* 去除多余空格
*
* @param s
* @return
*/
public StringBuilder removeSpace(String s) {
//s.trim();
int start = 0;
int end = s.length() - 1;
char[] chars = s.toCharArray();
while (chars[start] == 32) start++;
while (chars[end] == 32) end--;
StringBuilder sb = new StringBuilder();
int space = 0; //空格数量
for (int i = start; i <= end; i++) {
if (chars[i] != ' ') { //在这里防止同时出现两个空格的情况
sb.append(chars[i]);
space = 0;
} else {
space++;
if (space <= 1) {
sb.append(chars[i]);
}
}
}
return sb;
}
/**
* 反转整个字符串
*
* @param s
* @param i
* @param j
* @return
*/
public char[] reverseString(char[] s, int i, int j) {
for (; i <= j; i++, j--) {
char temp = s[i];
s[i] = s[j];
s[j] = temp;
}
return s;
}
方法1:不申请额外空间,在自身操作
/**
* 剑指 Offer 58 - II. 左旋转字符串
* @param s
* @param n
* @return
*/
public String reverseLeftWords2(String s, int n) {
//整个字符串反转
char[] chars = s.toCharArray();
reverseString(chars,0,chars.length-1);
//反转前length-n个
reverseString(chars,0,chars.length-n-1);
//反转后n个
reverseString(chars,chars.length-n,chars.length-1);
return new String(chars);
}
public char[] reverseString(char[] s, int i, int j) {
for (; i <= j; i++, j--) {
char temp = s[i];
s[i] = s[j];
s[j] = temp;
}
return s;
}
方法2:速度快
public String reverseLeftWords(String s, int n) {
String s1 = s.substring(0,n);
String s2 = s.substring(n); //左闭右开
StringBuffer sb = new StringBuffer();
sb.append(s2).append(s1);
return sb.toString();
}
方法1,暴力法:
/**
* 28. 找出字符串中第一个匹配项的下标
*
* @param haystack
* @param needle
* @return
*/
public int strStr(String haystack, String needle) {
char[] pattern = haystack.toCharArray();
char[] str = needle.toCharArray();
for (int i = 0; i <= pattern.length - str.length; i++) {
int index = i;
int j;
for (j = 0; j < str.length; j++) {
if (pattern[index++] != str[j]) {
break;
}
}
if (j == str.length) {
return i;
}
}
return -1;
}
方法2,kmp:
public int strStr2(String haystack, String needle) {
char[] pattern = haystack.toCharArray();
char[] str = needle.toCharArray();
int[] next = getNext(needle);
// System.out.println(Arrays.toString(next));
for (int i = 0, j = 0; i < pattern.length;i++ ) {
while (j > 0 && pattern[i] != str[j]) {
j = next[j - 1];
}
if ( pattern[i] == str[j]) {
j++;
}
if (j == str.length) return i - str.length + 1;
}
return -1;
}
//获取到一个字符串(子串) 的部分匹配值表
public int[] getNext(String s) {
int[] next = new int[s.length()];
next[0] = 0;
for (int i = 1, j = 0; i < s.length(); i++) {
while (j > 0 && s.charAt(i) != s.charAt(j)) {
j = next[j - 1]; //回退
}
if (s.charAt(i) == s.charAt(j)) {
j++;
}
next[i] = j;
}
return next;
}
常规解法:
/**
* 459. 重复的子字符串
*
* @param s
* @return
*/
public boolean repeatedSubstringPattern(String s) {
String str = s + s;
if (str.substring(1, str.length() - 1).contains(s)) return true;
return false;
}
kmp:
public boolean repeatedSubstringPattern(String s) {
int[] next = getNext(s);
// System.out.println(Arrays.toString(next));
int len = s.length();
//如果最后一个值有公共前后缀,满足可重复的话,next数组的最后一个值肯定是最大
//并且len - next[len-1] 是一个周期 len对len - next[len-1] 取模肯定变为0
if (next[len - 1] != 0 && len % (len - (next[len - 1] )) == 0) {
return true;
}
return false;
}
public int[] getNext(String s) {
int[] next = new int[s.length()];
next[0] = 0;
for (int i = 1, j = 0; i < s.length(); i++) {
while (j > 0 && s.charAt(i) != s.charAt(j)) { //这里while和if都可以
j = next[j - 1]; //回退
}
if (s.charAt(i) == s.charAt(j)) {
j++;
}
next[i] = j;
}
return next;
}