翻转字符串里的单词
本题较难,集合了字符串的几乎所有操作。
首先,需要去除字符串中多余的空格,保证首尾没有空格,且每个单词中间仅有一个空格。
然后翻转整个字符串,之后再翻转字符串中的每个单词。
其中去除多余空格,采用双指针法,类似于移除元素。
代码如下:
class Solution {
public String reverseWords(String s) {
char[] chars = s.toCharArray();
chars = removeSpaces(chars);
reverse(chars,0,chars.length - 1);
reverseEachWord(chars);
return new String(chars);
}
public char[] removeSpaces(char[] chars) {
int slow = 0;
for(int fast = 0;fast < chars.length;fast++){
if (chars[fast] != ' ') {
if(slow != 0){
chars[slow++] = ' ';
}
while (fast < chars.length && chars[fast] != ' ') {
chars[slow++] = chars[fast++];
}
}
}
char[] result = new char[slow];
System.arraycopy(chars, 0, result, 0, slow);
return result;
}
public void reverse(char[] chars,int slow,int fast) {
if (slow >= fast) {
return;
}
while (slow < fast) {
char temp = chars[slow];
chars[slow] = chars[fast];
chars[fast] = temp;
slow++;
fast--;
}
}
public void reverseEachWord(char[] chars){
int start = 0;
for(int end = 0;end <= chars.length;end++){
if(end == chars.length || chars[end] == ' '){
reverse(chars, start, end - 1);
start = end + 1;
}
}
}
}
找出字符串中的第一个匹配项的下标
KMP算法
首先找出待匹配字符串的next数组,然后再去匹配字符串,如果不等就回退到next数组的下标的前一个位置继续匹配,本题理解起来比较复杂。
代码如下:
class Solution {
public int strStr(String haystack, String needle) {
if(needle.length() == 0){
return 0;
}
int[] next = new int[needle.length()];
getNext(next,needle);
int j = 0;
for(int i = 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 - j + 1;
}
}
return -1;
}
public void getNext(int[] next,String s){
int j = 0;
next[0] = 0;
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;
}
}
}
重复的子字符串
本题理论上也是使用KMP算法,不过还可以进行移动匹配,就是新构建一个字符串为s+s,然后去除首尾字符,看新字符串是否包含原字符串,如果包含,那就说明是重复的子字符串。
代码如下:
class Solution {
public boolean repeatedSubstringPattern(String s) {
StringBuilder str = new StringBuilder();
str.append(s).append(s);
String modifiedStr = str.substring(1, str.length() - 1);
// 检查原字符串是否在修改后的字符串中
return modifiedStr.contains(s);
}
}
右旋转字符串
本题思路是先反转整个字符串,然后按照n,分别翻转前后部分即可
代码如下:
import java.util.*;
class Main{
public static void main (String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
scanner.nextLine();
String s = scanner.nextLine();
char[] chars = s.toCharArray();
reverse(chars,0,chars.length-1);
reverse(chars,0,n-1);
reverse(chars,n,chars.length-1);
System.out.println(new String(chars));
}
public static void reverse(char[] chars,int left,int right){
while(right > left){
char temp = chars[left];
chars[left] = chars[right];
chars[right] = temp;
right--;
left++;
}
}
}
今日八股
- 慢查询、原因以及优化方法
- undolog、redolog、binlog
- MySQL有哪些锁