1. 程式人生 > >ACM之反轉字符串裏的單詞

ACM之反轉字符串裏的單詞

ACM 字符串反轉

題目如下

技術分享圖片

對於字符串的操作一直都是非常重要的,而且有關字符串的題有各種非常奇妙的解法。我的感覺是這類題目要是方法或者邏輯不正確而去嘗試暴力解法,能把自己玩死......


方法一、利用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());
    }

}

測試:

方法一:技術分享圖片



方法二:技術分享圖片



方法三:技術分享圖片











ACM之反轉字符串裏的單詞