题目如下
对于字符串的操作一直都是非常重要的,而且有关字符串的题有各种非常奇妙的解法。我的感觉是这类题目要是方法或者逻辑不正确而去尝试暴力解法,能把自己玩死......
方法一、利用Split方法
用非常简洁而且容易理解的代码解决题目,思想是:利用正则表达式的split方法将字符串分解成单词存放在数组中,然后将数组逆序输出就ok。什么是正则表达式?这个都可以写一本书了,还得慢慢琢磨,先知道Split()方法就行。
split() 方法根据匹配给定的正则表达式来拆分字符串,参数为分隔符,当分隔符中有转义字符时,要加“\\”在分隔符前面。举个栗子,如果用“.”作为分隔符的话,就必须使用String.split("\\.")才能正确分割字符串。
然后逆序输出也不采用传统的for循环,用Collections.reverse()实现元素顺序的反转。(真的是简洁起来挡都挡不住系列)时间复杂度为O(N).
API是这样写的:
Java实现
public class StringReverseBter {
public static class Solution {
private String reverseWords(String s) {
if(s == null || s.length() == 0) return s;
/*
* @split()正则表达式
* +号表示匹配前面的子表达式一次或多次(大于等于1次)
* e.g.“zo+”能匹配“zo”以及“zoo”,但不能匹配“z”。+等价于{1,}*/
String[] words = s.trim().split(" +");
Collections.reverse(Arrays.asList(words));
//也可以使用StringBuilder来处理
StringBuilder sb = new StringBuilder();
for(int i = words.length-1;i >= 0;i--){
sb.append( words[i] + " ");
}
return sb.toString().trim();
//return String.join(" ", words);
}
}
}
方法二 先将整个字符串的字符反转,再将单个词的字符反转
e.g “the sky is blue”→ “eulb yks si eht” → “blue is sky the”
整个解决过程分为三个部分:字符串反转、单词反转、去多余的空格。时间复杂度为O(N)
String.trim()方法的作用是将String所有的前导空白字符和尾部空白字符移除
直接上代码
package Leetcode;
public class StringReverseBter2 {
private String Solution(String s){
if(s == null || s.length() < 1) return s;
String res;
char[] str = s.toCharArray();
int len = s.length();
reverse(str,0,len-1);//reverse the string letter by letter
reverseWord(str,len);
res = delSpaces(str,len);
return res;
}
/*
* reverse the string
* */
private void reverse(char[] ch,int i,int j){
while(i < j){
char temp = ch[i];
ch[i++] = ch[j];
ch[j--] = temp;
}
}
/*
* reverse the word letter by letter
* */
private void reverseWord(char[] ch ,int len){
int i = 0;
int j = 0;
//e.g "the sky is blue"
while(i < len){
while(i < j || i < len && ch[i] == ' ') i++;
while(j < i || j < len && ch[j] != ' ') j++;
//上面这两个循环的作用是找到一个单词的起始和结束位置坐标
//找到起始坐标i和结束坐标j之后利用reverse函数将其反转
reverse(ch,i,j-1);
}
}
/*
* delete the spaces
* e.g " the sky is blue"
* */
private String delSpaces(char[] ch,int len) {
int i = 0;
int j = 0;
while(i < len) {
while(i < len && ch[i] == ' ') i++;//找到空格后第一个字母的起始位置
while(i < len && ch[i] != ' ') ch[j++] = ch[i++]; //把第一个字母放在数组0的位置,并依次往后
while(i < len && ch[i] == ' ') i++;//继续将所有空格跳过
//上面三个循环结束后数组中存放的字母为“the”
if(i < len ) ch[j++] = ' ';//在the后面加上一个空格
}
return String.valueOf(ch).substring(0,j);
//有可能字符串是“the sky is blue ”最后有多个空格,所以直接取0—j
//或者可以用return new String(ch).trim();
}
public static void main(String[] args){
String test = " the sky is buleee ";
StringReverseBter2 srb2 = new StringReverseBter2();
System.out.println(srb2.Solution(test));
}
}
方法三、我第一次尝试时用的暴力法
这个写的就非常乱,没有逻辑,没有方法,看看就行。放在这里的原因是毕竟这也是我辛辛苦苦花时间写的,还是值得肯定的 >_<
package Leetcode;
import java.util.Scanner;
public class StringReverse {
public static String reverse(String s){
String res = "";
s = s.trim();
int len = s.length();
char[] tmp = new char[len];
//处理输入全为空格的情况
if(s.trim().isEmpty()){
return res;
}
//字符串处理
int index = 0;
for(int i=0 ; i<len ;i++){
tmp[i] = s.charAt(i);
if(s.charAt(i) == ' '){
index++;
}
}
String[] word = new String[index+1];
for(int i = 0;i<index+1;i++){
word[i] = "";
}
int index1 = 0;
for(int i = 0;i<=index;i++){
for(;index1<len;index1++){
if(s.charAt(index1) == ' '){
index1++;
break;
}else{
word[i] += s.charAt(index1);
//word[i] = word[i].trim();
}
}
}
for(int i = index;i >0;i--){
if(word[i] != ""){
res += word[i] + " ";
}
}
return res+word[0];
}
public static void main(String[] args){
String test = "the sky is blue";
System.out.println(reverse(test).trim());
}
}
测试:
方法一:
方法二:
方法三:
转载于:https://blog.51cto.com/acevi/2108348