算法數據結構面試分享(七)字符串按單詞反轉

字符串按單詞反轉

    這幾天一直有項目組活動,耽誤了沒有更新。今天我們一起看一下這道題: 字符串按照單詞反轉

一、確保我們理解了問題,並且嘗試一個例子,確認理解無誤。 
    我們應該見過這種問題,反轉一個字符串,如 “am" => "ma", 這道題也是這個思路,只是我們會以單詞爲單位。如"I am student" => "student am I". 好了我們現在可以提問了。
1. 單詞按照什麼分割呢? (按照空格)
2. 如果兩個單詞中間有多個空格,我們怎麼辦? (你想怎麼辦? - 其實我們至少要保證反轉之後字符串的長度不變)

二、想想你可以用什麼方法解決問題,你會選擇哪一種,爲什麼?
     如果我們已經指出來了單詞按照什麼分割的話,這道題可以利用List來解決,首先按照空格Split,把Split之後得到的數組再倒序的拼接起來。只是這種方法會丟失掉一些信息,如兩個單詞中間有多個空格呢,split之後我們就無從得知了。更重要的是,我們現在討論的是算法,我們肯定不希望面試者利用現有的數據結構,而是自己去寫。
  
三、 解釋你的算法和實現的方法
  我們先看一下字符串的反轉, “am" => "ma" , 如果有看過之前的文章,大家可能會想到收尾交換。申明兩個指針就好了。那如果我們按照這種方法,"I am student", 我們會得到“tneduts ma I", 現在我們將裏面的每一個單詞再反轉一下,是不是就得到了 "student am I" 了呢,那我們需要做的是識別裏面的空格,找出開始和結束的位置。
     現在我們還發現,其實兩次反轉的功能好像是一樣的。 寫成一個單獨的方法,重複調用。

四、寫代碼的時候,記住,一定要解釋你現在在幹什麼 
    直接上代碼,我們先處理首尾交換。一直一個字符數組,開始和結束爲止。

/// <summary>
        /// 我們將字符串input中,從input開始到end之間的子字符串反轉
        /// </summary>
        /// <param name="input"></param>
        /// <param name="begin"></param>
        /// <param name="end"></param>
        /// <returns></returns>
        public static void Revert(char[] input, int begin, int end)
        {
            if (input == null || input.Length < end || begin > end) throw new ArgumentException("Please check the input parameters.");

            for (int first = begin, last = end - 1; first < last; first++, last--)
            {
                char temp = input[first];
                input[first] = input[last];
                input[last] = temp;
            }
        }


接下來我們需要一個方法來調用它,該方法接受一個字符數組,第一步先首尾交換,反轉字符串。然後我們尋找裏面的空格,再將單詞首尾依次交換:

    public static void RevertWords(char[] input)
        {
            if (input != null && input.Length > 0)
            {
                Revert(input, 0, input.Length);

                int begin = 0;

                for (int index = begin; index < input.Length; index++)
                {
                    if (input[index] == ' ')
                    {
                        int end = index;
                        Revert(input, begin, end);
                        begin = end + 1;
                    }

                }
            }
        } 
五、 Workthrough
六、 修復缺陷

我們來測試一下這個方法:

        static void Main(string[] args)
        {
            char[] input = "I am student".ToArray();

            RevertWords(input);

            foreach (var c in input)
            {
                Console.Write(c);
            }
        }

大功告成了哈。歡迎大家關注我的公衆號,還有我的系列視頻教程, 數據結構與算法 微軟經典算法面試題輔導。大家有什麼更好的解法,也歡迎討論哈。 如果大家對以上的算法有什麼疑問,或者更好的解法,歡迎交流。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章