541. 反转字符串 II
//我们直接按题意进行模拟:反转每个下标从 2k 的倍数开始的
//,长度为 k 的子串。若该子串长度不足 k,则反转整个子串
//reverse(ch, i, Math.min(i + k, ch.length) - 1);实现
class Solution {
public String reverseStr(String s, int k) {
char[] ch = s.toCharArray();
for(int i = 0; i < ch.length; i += 2*k){
reverse(ch, i, Math.min(i + k, ch.length) - 1);
}
return new String(ch);
}
public void reverse(char[] arr, int left, int right){
while(left < right){
char temp = arr[left];
arr[left] = arr[right];
arr[right] = temp;
left++;
right--;
}
}
}
151. 颠倒字符串中的单词
class Solution {
public static String reverseWords(String s) {
if(s.isEmpty()) return "";
StringBuilder sb = new StringBuilder();
int left = 0;
int right = s.length() - 1;
while(s.charAt(left) == ' '){
left++;
}
while(s.charAt(right) == ' '){
right--;
}
while(left <= right){
int index = right;
while(index >= left && s.charAt(index) != ' '){
index--;
}
for(int i = index + 1; i <= right; i++){
sb.append(s.charAt(i));
}
if(index > left){
sb.append(' ');
}
while( index >= left && s.charAt(index) == ' ' ){
index--;
}
right = index;
}
return sb.toString();
}
}
剑指 Offer 58 - II. 左旋转字符串
//revserse()中用while判断比用for更加明了
//原地翻转字符串一般可组合局部反转和整体反转来实现
class Solution {
public String reverseLeftWords(String s, int n) {
char[] ch = s.toCharArray();
reverse(ch, 0, n - 1);
reverse(ch, n, ch.length - 1);
reverse(ch, 0, ch.length - 1);
return new String(ch);
}
public void reverse(char[] ch, int left, int right){
while(left < right){
char temp = ch[left];
ch[left] = ch[right];
ch[right] = temp;
left++;
right--;
}
}
}
28. 实现 strStr()
详见https://sumschol.github.io/
class Solution {
public int strStr(String haystack, String needle) {
if(needle.length() == 0){
return 0;
}
int[] next = new int[needle.length()];
getNext(next, needle);
for(int i = 0, j = 0;i < haystack.length(); i++){
while(j > 0 && haystack.charAt(i) != needle.charAt(j)){
j = next[j - 1];
}
if(haystack.charAt(i) == needle.charAt(j)){
j++;
}
if(j == needle.length()){
return i - needle.length() + 1;
}
}
return -1;
}
public void getNext(int[] next, String needle){
int j = 0;
next[0] = j;
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;
}
}
}
- 重复的子字符串
class Solution {
public boolean repeatedSubstringPattern(String s) {
int[] next = new int[s.length()];
getNext(next, s);
if(next[next.length - 1] == 0){
return false;
}
if(s.length() % (s.length() - next[next.length - 1]) == 0){
return true;
}
return false;
}
public void getNext(int[] next, String s){
int j = 0;
next[0] = j;
for(int i = 1; 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;
}
}
}