算法数据结构面试分享(七)字符串按单词反转

字符串按单词反转

    这几天一直有项目组活动,耽误了没有更新。今天我们一起看一下这道题: 字符串按照单词反转

一、确保我们理解了问题,并且尝试一个例子,确认理解无误。 
    我们应该见过这种问题,反转一个字符串,如 “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);
            }
        }

大功告成了哈。欢迎大家关注我的公众号,还有我的系列视频教程, 数据结构与算法 微软经典算法面试题辅导。大家有什么更好的解法,也欢迎讨论哈。 如果大家对以上的算法有什么疑问,或者更好的解法,欢迎交流。

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