一、151.翻转字符串里的单词
题目:给你一个字符串
s
,请你反转字符串中 单词 的顺序。单词 是由非空格字符组成的字符串。
s
中使用至少一个空格将字符串中的 单词 分隔开。返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。
注意:输入字符串
s
中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。
学习链接:翻转字符串里的单词状态:做出来了
我的思路:利用双指针,俩指针从字符串尾部开始遍历,左指针指向单词的首部,右指针指向单词的尾部 ,然后一直重复这样的动作
代码随想录思路:写三个函数,第一个函数去掉多余空格(包括首尾,中间多余空格),第二个函数反转整个字符串,第三个函数反转单词
我的思路:
class Solution {
public String reverseWords(String s) {
String result="";
Boolean flag=true;
int left=0;int right=s.length()-1;
while(left<s.length()&&s.charAt(left)!=' ')left++;
while(right>=0){
while(right>=0&&s.charAt(right)==' ')right--;
if(right<0)break;
int start=right;
while(start>=0&&s.charAt(start)!=' ')start--;
result+=s.substring(start+1,right+1)+" ";
right=start;
}
return result.trim();
}
}
代码随想录思路:
class Solution {
/**
* 不使用Java内置方法实现
* <p>
* 1.去除首尾以及中间多余空格
* 2.反转整个字符串
* 3.反转各个单词
*/
public String reverseWords(String s) {
// System.out.println("ReverseWords.reverseWords2() called with: s = [" + s + "]");
// 1.去除首尾以及中间多余空格
StringBuilder sb = removeSpace(s);
// 2.反转整个字符串
reverseString(sb, 0, sb.length() - 1);
// 3.反转各个单词
reverseEachWord(sb);
return sb.toString();
}
private StringBuilder removeSpace(String s) {
// System.out.println("ReverseWords.removeSpace() called with: s = [" + s + "]");
int start = 0;
int end = s.length() - 1;
while (s.charAt(start) == ' ') start++;
while (s.charAt(end) == ' ') end--;
StringBuilder sb = new StringBuilder();
while (start <= end) {
char c = s.charAt(start);
if (c != ' ' || sb.charAt(sb.length() - 1) != ' ') {
sb.append(c);
}
start++;
}
// System.out.println("ReverseWords.removeSpace returned: sb = [" + sb + "]");
return sb;
}
/**
* 反转字符串指定区间[start, end]的字符
*/
public void reverseString(StringBuilder sb, int start, int end) {
// System.out.println("ReverseWords.reverseString() called with: sb = [" + sb + "], start = [" + start + "], end = [" + end + "]");
while (start < end) {
char temp = sb.charAt(start);
sb.setCharAt(start, sb.charAt(end));
sb.setCharAt(end, temp);
start++;
end--;
}
// System.out.println("ReverseWords.reverseString returned: sb = [" + sb + "]");
}
private void reverseEachWord(StringBuilder sb) {
int start = 0;
int end = 1;
int n = sb.length();
while (start < n) {
while (end < n && sb.charAt(end) != ' ') {
end++;
}
reverseString(sb, start, end - 1);
start = end + 1;
end = start + 1;
}
}
}
二、卡码网:55.右旋转字符串
题目:字符串的右旋转操作是把字符串尾部的若干个字符转移到字符串的前面。给定一个字符串 s 和一个正整数 k,请编写一个函数,将字符串中的后面 k 个字符移到字符串的前面,实现字符串的右旋转操作。
例如,对于输入字符串 "abcdefg" 和整数 2,函数应该将其转换为 "fgabcde"。
学习链接:右旋转字符串状态:做出来了
思路:Java不能原地修改字符串,原地修改符串的思路,先反转整个字符串,再0到n,n到n.lenth-1就行了。Java是直接截取后面一段到前面,思路比较简单。但这里还是放原地修改的思路,虽然对空间复杂度没有帮助,但是对算法思路有提示
import java.util.*; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int k = Integer.parseInt(sc.nextLine()); String s = sc.nextLine(); char[] c = s.toCharArray(); reverseString(c, 0, c.length - 1); reverseString(c, 0, k - 1); reverseString(c, k, c.length - 1); System.out.println(new String(c)); } public static void reverseString(char[] a, int left, int right) { while (left <= right) { char temp=a[left]; a[left]=a[right]; a[right]=temp; left++; right--; } } }
三、28. 实现 strStr()
题目:给你两个字符串
haystack
和needle
,请你在haystack
字符串中找出needle
字符串的第一个匹配项的下标(下标从 0 开始)。如果needle
不是haystack
的一部分,则返回-1
。
学习链接:实现 strStr()状态:没做出来
思路:利用kmp算法,求出next数组,即最大公共前缀和,解决了字符串匹配的问题。学习链接在上方,有兴趣的可以了解一下kmp算法
class Solution {
public int strStr(String haystack, String needle) {
int[] next=getNext(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 static int[] getNext(String needle){
int[] next=new int[needle.length()];
int j=0;
for(int i=1;i<needle.length();i++){
while(j>0&&next[i]!=next[j])j=next[j-1];
if(next[i]==next[j])j++;
next[i]=j;
}
return next;
}
}