C#代码随想录算法训练营day8|字符串

LeetCode344 反转字符串

题目描述:

编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。
不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。

示例 1:
输入:s = [“h”,“e”,“l”,“l”,“o”]
输出:[“o”,“l”,“l”,“e”,“h”]

示例 2:
输入:s = [“H”,“a”,“n”,“n”,“a”,“h”]
输出:[“h”,“a”,“n”,“n”,“a”,“H”]

思路:

第一反应是用栈,但是题目本身无返回值,且要求给另外的数组分配额外的空间,所以行不通,一种思路是直接前后两两交换,还有就是用双指针。

代码:
直接交换:
public class Solution {
    public void ReverseString(char[] s) {
            int len = s.Length;
            for (int i = 0; i < len / 2; i++)
            {
                char temp = s[i];
                s[i] = s[s.Length - i - 1];
                s[s.Length - i - 1] = temp;
            }
    }
}
双指针:
public class Solution {
    public void ReverseString(char[] s)
        {
            int len = s.Length;
            int left = 0, right = len - 1;
            while (left < right)
            {
                char temp = s[left];
                s[left] = s[right];
                s[right] = temp;
                left++;
                right--;
            }
        }
}

LeetCode541 反转字符串II

题目描述:

给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。
如果剩余字符少于 k 个,则将剩余字符全部反转。
如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。

示例 1:
输入:s = “abcdefg”, k = 2
输出:“bacdfeg”

示例 2:
输入:s = “abcd”, k = 2
输出:“bacd”

思路:

双指针,和上一题类似。

代码:
public class Solution {
     public string ReverseStr(string s, int k)
        {
            int len = s.Length;
            char[] arr = s.ToCharArray();
            for (int i = 0; i < len; i += 2 * k)
            {
                Swap(arr, i, Math.Min(i + k, len) - 1);
            }
            return new string(arr);
        }

        public void Swap(char[] s, int left, int right)
        {
            while (left < right)
            {
                char tem = s[left];
                s[left] = s[right];
                s[right] = tem;
                left++;
                right--;
            }
        }
}

LeetCode 剑指 Offer 05. 替换空格

题目描述:

请实现一个函数,把字符串 s 中的每个空格替换成"%20"。

示例 1:
输入:s = “We are happy.”
输出:“We%20are%20happy.”

思路:

双指针,先确定数组中空格的个数count,之后扩容数组(数组原本长度+空格个数*2),再采用双指针从后向前遍历,左指针从数组原本长度减1开始,右指针从数组扩容后长度减1开始。

代码:
public class Solution {
    public string ReplaceSpace(string s) {
            char[] arr =  s.ToCharArray();
            int count = 0;      //统计空格数量
            for (int i = 0; i < s.Length; i++)
            {
                if (s[i] == ' ')
                {
                    count++;
                }
            }
            Array.Resize(ref arr, s.Length + count * 2);//数组扩容
            for (int i = s.Length - 1, j = arr.Length - 1; i < j; i--, j--)
            {
                if (s[i] != ' ')
                {
                    arr[j] = s[i];
                }
                else
                {
                    arr[j] = '0';
                    arr[j - 1] = '2';
                    arr[j - 2] = '%';
                    j -= 2;
                }
            }
            return new string(arr);
    }
}

LeetCode151 反转字符串中的单词

题目描述:

给你一个字符串 s ,请你反转字符串中 单词 的顺序。
单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。
返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。
注意:输入字符串 s中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。

示例 1:
输入:s = “the sky is blue”
输出:“blue is sky the”

示例 2:
输入:s = " hello world "
输出:“world hello”
解释:反转后的字符串中不能存在前导空格和尾随空格。

示例 3:
输入:s = “a good example”
输出:“example good a”
解释:如果两个单词间有多余的空格,反转后的字符串需要将单词间的空格减少到仅有一个。

思路:

1.直接库函数。

代码:
public class Solution {
    public string ReverseWords(string s) {
        var strings = s.Split(' ').Where(item => item != ""); //以空格进行,分割,用泛型var存储
        return string.Join(" ", strings.Reverse()); //反转字符,然后字符串拼接加上一个空格
    }
}

2.(1)快慢指针去除首尾以及中间多余空格(2)整个字符串反转(3)单词反转

代码:
public class Solution {
    public string ReverseWords(string s)
        {
            char[] arr = s.ToCharArray();
            //1.去除首尾以及中间多余空格
            arr = RemoveSpace(arr);
            //2.整个字符串反转
            Reverse(arr, 0, arr.Length - 1);
            //3.单词反转
            ReverseWord(arr);
            return new string(arr);
        }

        public char[] RemoveSpace(char[] chars)
        {
            int slow = 0;
            for (int fast = 0; fast < chars.Length; fast++)
            {
                //先用fast消除所有空格
                if (chars[fast] != ' ')
                {
                    //再用slow加空格,除了第一个单词外,单词末尾要加空格
                    if (slow != 0)
                    {
                        chars[slow++] = ' ';
                    }
                    //fast遇到空格或遍历到字符串末尾,就证明一个单词遍历完成
                    while (fast < chars.Length && chars[fast] != ' ')
                    {
                        chars[slow++] = chars[fast++];
                    }
                }
            }
            char[] newChars = new char[slow];
            Array.Copy(chars, 0, newChars, 0, slow);
            return newChars;
        }

        public void Reverse(char[] arr, int left, int right)
        {
            while (left < right)
            {
                char tem = arr[left];
                arr[left] = arr[right];
                arr[right] = tem;
                left++;
                right--;
            }
        }

        public void ReverseWord(char[] arr)
        {
            int start = 0;
            int end = 0;
            while (end <= arr.Length)
            {
                if (end == arr.Length || arr[end] == ' ')
                {
                    Reverse(arr, start, end - 1);
                    start = end + 1;
                }
                end++;
            }
        }
}

3.栈

代码:
public class Solution {
    public string ReverseWords(string s) {
        Stack<char> stack = new Stack<char>();
            StringBuilder res = new StringBuilder();
            s = s.Trim();
            for (int i = s.Length - 1; i >= 0; i--)
            {
                char c = s[i];
                if (c == ' ')
                {
                    if (stack.Count > 0)
                    {
                        res.Append(new string(stack.ToArray()));
                        res.Append(" ");
                        stack.Clear();
                    }
                }
                else
                {
                    stack.Push(c);
                }
            }
            res.Append(new string(stack.ToArray()));
            return res.ToString();
    }
}

剑指 Offer 58 - II. 左旋转字符串

题目描述:

字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。

示例 1:
输入: s = “abcdefg”, k = 2
输出: “cdefgab”

示例 2:
输入: s = “lrloseumgh”, k = 6
输出: “umghlrlose”

思路:

双指针,以n为边界,反转遍历三次。

代码:
public class Solution {
    public string ReverseLeftWords(string s, int n) {
            char[] arr = s.ToCharArray();
            Reverse(arr, 0, arr.Length - 1);
            Reverse(arr, 0, arr.Length - 1 - n);
            Reverse(arr, arr.Length - n, arr.Length - 1);
            return new string(arr);
    }

    public void Reverse(char[] arr, int left, int right)
        {
            while (left < right)
            {
                char tem = arr[left];
                arr[left] = arr[right];
                arr[right] = tem;
                left++;
                right--;
            }
        }
}

你可能感兴趣的:(算法训练营,算法,c#,leetcode)