一、反转字符串
1. 344【反转字符串】
- 题目: 编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
- 代码:
class Solution {
public void reverseString(char[] s) {
int left = 0;
int right = s.length-1;
while (left < right){
s[left] ^= s[right];
s[right] ^= s[left];
s[left] ^= s[right];
left++;
right--;
}
}
}
2. 541【反转字符串II】
- 题目: 给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。
- 如果剩余字符少于 k 个,则将剩余字符全部反转。
- 如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。
- 代码:
class Solution {
public String reverseStr(String s, int k) {
char[] charArr = s.toCharArray();
for (int i = 0; i < s.length(); i+=2*k) {
if(i + k > s.length()){
reverse(charArr,i,s.length()-1);
break;
}
reverse(charArr,i,i+k-1);
}
String str = String.valueOf(charArr);
return str;
}
public void reverse(char[] s,int left,int right) {
while (left < right){
s[left] ^= s[right];
s[right] ^= s[left];
s[left] ^= s[right];
left++;
right--;
}
}
}
3. 151【翻转字符串里的单词】
- 题目: 给你一个字符串 s ,请你反转字符串中单词的顺序。单词是由非空格字符组成的字符串。s中使用至少一个空格将字符串中的单词分隔开。返回单词顺序颠倒且单词之间用单个空格连接的结果字符串。
注意:输入字符串 s中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。 - 代码:
class Solution {
public String reverseWords(String s) {
StringBuilder sb = new StringBuilder();
int left = 0;
int right = s.length()-1;
while (s.charAt(left) == ' '){
left++;
}
while (s.charAt(right) == ' '){
right--;
}
for (int i = left; i < right+1; i++) {
if(s.charAt(i)==' ' && s.charAt(i-1)==' '){
continue;
}
sb.append(s.charAt(i));
}
int len = sb.length();
char[] charArr = new char[len];
for (int i = 0; i < len; i++) {
charArr[i] = sb.charAt(len-i-1);
}
left = 0;
for (int i = 0; i < len; i++) {
if(charArr[i] == ' '){
reverse(charArr,left,i-1);
left = i+1;
}
if(i == len-1){
reverse(charArr,left,i);
}
}
String str = String.valueOf(charArr);
return str;
}
public void reverse(char[] s,int left,int right) {
while (left < right){
s[left] ^= s[right];
s[right] ^= s[left];
s[left] ^= s[right];
left++;
right--;
}
}
}
4. 卡码网【右旋字符串】
- 题目: 字符串的右旋转操作是把字符串尾部的若干个字符转移到字符串的前面。给定一个字符串 s 和一个正整数 k,请编写一个函数,将字符串中的后面 k 个字符移到字符串的前面,实现字符串的右旋转操作。
例如,对于输入字符串 “abcdefg” 和整数 2,函数应该将其转换为 “fgabcde”。
输入:输入共包含两行,第一行为一个正整数 k,代表右旋转的位数。第二行为字符串 s,代表需要旋转的字符串。
输出:输出共一行,为进行了右旋转操作后的字符串。 - 代码:
import java.util.Scanner;
public void reverse(char[] s,int left,int right) {
while (left < right){
s[left] ^= s[right];
s[right] ^= s[left];
s[left] ^= s[right];
left++;
right--;
}
}
public void rightReverse(){
Scanner scan = new Scanner(System.in);
String s = scan.next();
int k = scan.nextInt();
char[] charArr = s.toCharArray();
reverse(charArr,0,s.length()-1);
reverse(charArr,0,k-1);
reverse(charArr,k,s.length()-1);
System.out.println(String.valueOf(charArr));
}
二、替换字符串中某些字符
1. 卡码网【替换数字】
- 题目: 给定一个字符串 s,它包含小写字母和数字字符,请编写一个函数,将字符串中的字母字符保持不变,而将每个数字字符替换为number。
例如,对于输入字符串 “a1b2c3”,函数应该将其转换为 “anumberbnumbercnumber”。
对于输入字符串 “a5b”,函数应该将其转换为 “anumberb”
输入:一个字符串 s,s 仅包含小写字母和数字字符。
输出:打印一个新的字符串,其中每个数字字符都被替换为了number
样例输入:a1b2c3
样例输出:anumberbnumbercnumber
数据范围:1 <= s.length < 10000。 - 代码:
import java.util.Scanner;
public void replaceDigit(){
Scanner scan = new Scanner(System.in);
String s = scan.next();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
if(s.charAt(i)>='0' && s.charAt(i)<='9'){
sb.append("number");
}else{
sb.append(s.charAt(i));
}
}
scan.close();
System.out.println(sb);
}
三、KMP算法
1. 28【找出字符串中第一个匹配项的下标】
- 题目: 给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标(下标从 0 开始)。如果 needle 不是 haystack 的一部分,则返回 -1 。
示例 1:
输入:haystack = “sadbutsad”, needle = “sad”
输出:0
解释:“sad” 在下标 0 和 6 处匹配。第一个匹配项的下标是 0 ,所以返回 0 。 - 代码:
class Solution {
public int strStr(String haystack, String needle) {
if(needle.length() == 0){
return 0;
}
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;
}
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-needle.length()+1;
}
}
return -1;
}
}
2. 459【重复的子字符串】
- 题目: 给定一个非空的字符串 s ,检查是否可以通过由它的一个子串重复多次构成。
- 代码:
class Solution {
public boolean repeatedSubstringPattern(String s) {
int len = s.length();
int[] next = new int[len];
int j = 0;
next[j] = 0;
for (int i = 1; i < len; 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;
}
if(next[len-1]>0 && len%(len-next[len-1])==0){
return true;
}
return false;
}
}