Python Leek brush question 07- reverse string & replace spaces & left rotate string

344. Reverse a String

Link to the topic : https://leetcode.cn/problems/reverse-string/

Title description : Write a function whose function is to reverse the input string. The input string is given as a char[] array of characters.

Don't allocate extra space for another array, you have to modify the input array in-place, using O(1) extra space to solve this problem.

You can assume that all characters in the array are printable characters in the ASCII code table.

case :

输入:["h","e","l","l","o"]
输出:["o","l","l","e","h"]

Achieve :

Method one :

class Solution:
    def reverseString(self, s: List[str]) -> None:
        """
        Do not return anything, modify s in-place instead.
        s[::-1]表示反转s中的元素
        s[:]表示数组中所有子模块
        """
        s[:]=s[::-1] #将原数组反转后赋值给s中每一个对应的位置

Method 2 : Double pointer
Initialization: Set two pointers l and r to point to the first and last elements of the list.
Step: Exchange the corresponding elements of s[l] and s[r], and update the pointer position (l+=1, r-=1) until Two pointers meet
Time complexity: O(N)

class Solution:
    def reverseString(self, s: List[str]) -> None:
        """
        Do not return anything, modify s in-place instead.
        """
        l,r = 0,len(s)-1
        while l<r:
            s[l],s[r] = s[r],s[l]
            l += 1
            r -= 1

541. Reverse a String II

Link to the topic : https://leetcode.cn/problems/reverse-string-ii/

Title description : Given a string s and an integer k, counting from the beginning of the string, every time 2k characters are counted, reverse the first k characters of the 2k characters.

If the remaining characters are less than k, reverse all remaining characters.

If the remaining characters are less than 2k but greater than or equal to k, reverse the first k characters and leave the rest as they are.

case :

输入: s = "abcdefg", k = 2
输出: "bacdfeg"

Achieve :

class Solution:
    def reverseStr(self, s: str, k: int) -> str:
        p = 0 
        while p < len(s):
            p2 = p + k 
            s = s[:p] + s[p:p2][::-1] + s[p2:]
            p = p + 2*k
        return s

Sword Pointer Offer 05. Replace spaces

Link to the topic : https://leetcode.cn/problems/ti-huan-kong-ge-lcof/

Title description: Please implement a function to replace each space in the string s with "%20".

case :

 1: 输入:s = "We are happy."
输出:"We%20are%20happy."

Achieve :

Method 1 : Traversing and adding
In languages ​​such as Python and Java, strings are designed as "immutable" types, that is, a character of a string cannot be directly modified, and a new string needs to be created to implement it.

Algorithm flow:
Initialize a list (Python) / StringBuilder (Java), record it as res;
traverse each character c in the list s:
when c is a space: add the string "%20" to res;
when c is not When there is a space: add character c after res;
convert the list res into a string and return it.
Complexity analysis:
time complexity O(N)O(N)O(N): traversal uses O(N)O(N)O(N), and each round of adding (modifying) character operations uses O(1)O( 1) O(1);
space complexity O(N)O(N)O(N): Python's new list and Java's new StringBuilder both use extra space of linear size.

class Solution:
    def replaceSpace(self, s: str) -> str:
        res = []
        for c in s:
            # 当 c 为空格时:向 res 后添加字符串 "%20" 
            if c == ' ': res.append("%20")
            # 当 c 不为空格时:向 res 后添加字符 c 
            else : res.append(c)
        # 将列表 res 转化为字符串并返回
        return "".join(res)

Method 2 : Double pointer method

First expand the array to the size after replacing each space with "%20".

Then replace the space from the back to the front, that is, the double pointer method, the process is as follows:

i points to the end of the new length and j points to the end of the old length.

class Solution:
    def replaceSpace(self, s: str) -> str:
        counter = s.count(' ')
        res = list(s)  #转换为列表
        # 每碰到一个空格就多扩展两个格子
        res.extend([' ']* counter * 2)

        # left为原字符串的末尾,right为拓展长度后的末尾
        left,right = len(s) - 1,len(res) - 1

        while left >= 0:
            if res[left] != ' ':
                res[right] = res[left]
                right -= 1
            else:
                # [right-2,right),左闭右开
                res[right - 2:right + 1] = '%20'
                right -=3
            left -= 1
        return ''.join(res)

Previously completed double-pointer solutions related topics are:

27. Remove elements - Leetcode

15. Sum of Three Numbers - Leetcode

18. Sum of Four Numbers - Leetcode

206. Reverse Linked List - Leetcode

142. Linked List II - Leetcode

344. Reverse a String - Leetcode

151. Flip words in a string

Link to the topic : https://leetcode.cn/problems/reverse-words-in-a-string/

Title description : Given a string s, please reverse the order of the words in the string .

A word is a string consisting of non-whitespace characters. Separate the wordss in the string with at least one space .

Returns the resulting string with the words reversed and words joined with a single space.

**Note:** sThere may be leading spaces, trailing spaces, or multiple spaces between words in the input string. In the returned result string, words should only be separated by a single space and not contain any extra spaces.

case :

示例1:
输入: "the sky is blue"
输出: "blue is sky the"

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

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

Ideas :

  • remove extra spaces
  • reverse the entire string
  • reverse each word

For example, the source string is: "the sky is blue "

  • Remove extra spaces: “the sky is blue”
  • String reverse: "eulb si yks eht"
  • Word reversal: "blue is sky the"

Achieve :

method one:

class Solution:
#1.去除多余的空格
    def trim_spaces(self,s):     
        n=len(s)
        left=0
        right=n-1
    
        while left<=right and s[left]==' ':       #去除开头的空格
            left+=1
        while left<=right and s[right]==' ':        #去除结尾的空格
            right=right-1
        tmp=[]
        while left<=right:                                    #去除单词中间多余的空格
            if s[left]!=' ':
                tmp.append(s[left])
            elif tmp[-1]!=' ':                                  
                #当前位置是空格,但是相邻的上一个位置不是空格,则该空格是合理的
                tmp.append(s[left])
            left+=1
        return tmp
#2.翻转字符数组
    def reverse_string(self,nums,left,right):
        while left<right:
            nums[left], nums[right]=nums[right],nums[left]
            left+=1
            right-=1
        return None
#3.翻转每个单词
    def reverse_each_word(self, nums):
        start=0
        end=0
        n=len(nums)
        while start<n:
            while end<n and nums[end]!=' ':
                end+=1
            self.reverse_string(nums,start,end-1)
            start=end+1
            end+=1
        return None

# 测试用例:"the sky is blue"
    def reverseWords(self, s: str) -> str:        
        #输出:['t', 'h', 'e', ' ', 's', 'k', 'y', ' ', 'i', 's', ' ', 'b', 'l', 'u', 'e'
        l = self.trim_spaces(s) 
        #输出:['e', 'u', 'l', 'b', ' ', 's', 'i', ' ', 'y', 'k', 's', ' ', 'e', 'h', 't']
        self.reverse_string( l,  0, len(l) - 1)
        #输出:['b', 'l', 'u', 'e', ' ', 'i', 's', ' ', 's', 'k', 'y', ' ', 't', 'h', 'e']
        self.reverse_each_word(l)
        #输出:blue is sky the
        return ''.join(l)  

Method 2 : Double pointer method

Algorithm analysis:
Traverse the string sss in reverse order, record the left and right index boundaries iii, jjj of the word;
each time the boundary of a word is determined, add it to the word list resres;
finally, concatenate the word list into a string and return it.
Complexity analysis:
time complexity O(N)O(N)O(N): where NNN is the length of the string sss, and the string is traversed linearly.
Space complexity O(N)O(N)O(N): The total length of the strings in the newly created list(Python) or StringBuilder(Java)≤N\leq N≤N, occupying O(N)O(N) O(N) extra space.

Link to the source of problem-solving ideas: https://leetcode.cn/problems/reverse-words-in-a-string/solutions/195397/151-fan-zhuan-zi-fu-chuan-li-de-dan-ci- shuang-zh-2/

class Solution:
    def reverseWords(self, s: str) -> str:
        s = s.strip() #删除首尾空格
        i = j = len(s) -1
        res = []
        while i>= 0:
            # 搜索首个空格
            while i >= 0 and s[i] != ' ': i -= 1 
            # 添加单词
            res.append(s[i + 1 : j + 1])
            # 跳过单词间的空格
            while s[i] == ' ': i -= 1
            # j指向下个单词的尾字符
            j = i
        # 凭借并返回
        return ' '.join(res)

Sword Pointing to Offer58-II. Left Rotate String

Link to the topic : https://leetcode.cn/problems/zuo-xuan-zhuan-zi-fu-chuan-lcof/

Title description : The left rotation operation of a string is to transfer several characters in front of the string to the end of the string. Please define a function to realize the function of string left rotation operation. For example, if you input the string "abcdefg" and the number 2, the function will return the result "cdefgab" obtained by rotating left by two bits.

case :

输入: s = "abcdefg", k = 2
输出: "cdefgab"

Achieve :

Method 1 : Slicing

class Solution:
    def reverseLeftWords(self, s: str, n: int) -> str:
        return s[n:] + s[0:n]

Method 2 : Partial reversal + overall reversal

class Solution:
    def reverseLeftWords(self, s: str, n: int) -> str:
        s = list(s)
        # 1.反转区间为前n的子串
        s[0:n] = list(reversed(s[0:n]))
        # 2.反转区间为n到末尾的子串
        s[n:] = list(reversed(s[n:]))
        # 3.反转整个字符串
        s.reverse()

        return "".join(s)

Method three :

class Solution:
    def reverseLeftWords(self, s: str, n: int) -> str:
        new_s = ''
        for i in range(len(s)):
            j = (i+n)%len(s)
            new_s = new_s +s[j]
        return new_s

Guess you like

Origin blog.csdn.net/modi88/article/details/127750820