zoukankan      html  css  js  c++  java
  • 0151-leetcode算法实现之翻转字符串里的单词-reverse-words-in-a-string-python&golang实现

    给你一个字符串 s ,逐个翻转字符串中的所有 单词 。

    单词 是由非空格字符组成的字符串。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"
    解释:如果两个单词间有多余的空格,将翻转后单词间的空格减少到只含一个。
    示例 4:

    输入:s = " Bob Loves Alice "
    输出:"Alice Loves Bob"
    示例 5:

    输入:s = "Alice does not even like bob"
    输出:"bob like even not does Alice"

    提示:

    1 <= s.length <= 104
    s 包含英文大小写字母、数字和空格 ' '
    s 中 至少存在一个 单词

    进阶:

    请尝试使用 O(1) 额外空间复杂度的原地解法。

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/reverse-words-in-a-string

    python

    # 翻转字符串里的单词
    class Solution:
        def reverseWords(self, s: str) -> str:
            """
            双指针,字符串的综合操作
            解题思路如下:
            -1.移除多余空格
                -1.1 rm开头空字符,遇空left指针++,遇非空停止
                -1.2 rm结尾字符,遇空right--,遇非空停止
                -1.3 rm串中字符,开辟temp list容器,left从1.1值++遍历,非空加入list,第一个空加入list
            -2.将整个字符串反转
                -整个字符串数组全部反转,左右指针元素互换,left++, right--, 相遇即停
            -3.将每个单词反转
                -3.1 设置start,end指针,初始化0
                -3.2 start用于每个单词第一个字符,end遍历到指向单词后的空格停止,
                -3.3 反转该单词数组
                -3.4 start=end+1, end++, start重新指向单词字符数组的第一个元素,end也从空格+1
                -3.5 重复3.2 3.3 3.4, start=n停,反转回每个单词
            -4.将数组转成string
            :param s:
            :return:
            """
            l = self.rmExtraSpaces(s) # 1.删除多余空格
            # ['i', 't', ' ', 'i', 's', ' ', 'r', 'a', 'i', 'n', 'i', 'n', 'g', ' ', 't', 'o', 'd', 'a', 'y']
            self.reverseStrs(l, 0, len(l) - 1) # 2.翻转字符
            # ['y', 'a', 'd', 'o', 't', ' ', 'g', 'n', 'i', 'n', 'i', 'a', 'r', ' ', 's', 'i', ' ', 't', 'i']
            self.reverseEachWord(l) # 3.翻转每个单词
            # ['t', 'o', 'd', 'a', 'y', ' ', 'r', 'a', 'i', 'n', 'i', 'n', 'g', ' ', 'i', 's', ' ', 'i', 't']
            return ''.join(l)
    
        # 1.去除头中尾空格
        def rmExtraSpaces(self, s):
            n = len(s)
            left = 0
            right = n - 1
            # rm开头空格
            while left <= right and s[left] == ' ': # 只有开头是空格或多个空格下,left++,直到遇到字符非空字符
                left += 1
            # rm结尾空格
            while left <= right and s[right] == ' ': # 只有结尾是空格或多个空格下,right--,直到遇到字符非空字符
                right -= 1
            # rm串中多余空格
            tmp = []
            while left <= right: # 由于第一个检查是从头加,如果空就检查末尾字符是否非空,即遇到第一个空格符append进temp,第二个空格符略掉,即实现rm多余空格
                if s[left] != ' ': # 遇到非空字符,append进temp
                    tmp.append(s[left])
                # 当前位置是空格,但是相邻的上一个位置不是空格,则该空格是合理的
                elif tmp[-1] != ' ': # 检查末尾字符,如果非空,append进temp
                    tmp.append(s[left])
                left += 1 # left指针++
            return tmp
    
        # 2.翻转字符数组
        def reverseStrs(self, strs, left, right):
            """
            反转字符数组,左右指针元素互换,left++,right--,直到相遇
            :param strs:
            :param left:
            :param right:
            :return:
            """
            while left < right:
                strs[left], strs[right] = strs[right], strs[left]
                left += 1
                right -= 1
            return None
    
        # 3.翻转每个单词
        def reverseEachWord(self, strs):
            start, end = 0, 0
            n = len(strs)
            while start < n:
                while end < n and strs[end] != ' ': # start每次指向当轮非空字符,end不断累加,遇空break
                    end += 1
                self.reverseStrs(strs, start, end-1) # 翻转连续字符,即一个单词
                start = end + 1 # start指针指向空格的下一个字符
                end += 1 # end指针继续, end++,重复
            return None
    ----
    class Solution:
        def reverseWords1(self, s: str) -> str:
            """
            双指针,代码简化,时间O(n), 空间O(n)->python list <= O(n)
            思路:
            -1.利用库函数rm首尾空格
            -2.初始化指针,i,j->n-1,开辟新数组
            -3.移动i指针,只要是单词字符i--,直到遇到空格符,break
            -4.由3步的i(空格)及j即可确认当前指针范围内的某个单词,加进数组
            -5.i指针继续左移,跳过单词间空格,每遇空格,i--,直到遇到下一单词尾子符,break
            -6.令j=i,即确认下个单词的尾部,i继续左移,重复3 4步
            -7.当i<0说明i已经到达字符串的头部位置,break 3 4 5 6步,拼接字符串后返回
            :param s:
            :return:
            """
            s = s.strip() # rm首尾空格
            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 = i # 指向下个单词尾子符
            return ' '.join(res) # 拼接返回
    
    
    if __name__ == "__main__":
        str1 = "it is raining today"
        str2 = " roast pork is very  yummy "
        test = Solution()
        print(test.reverseWords(str1))
        print(test.reverseWords(str2))
    
    

    golang

    func reverseWordsOpt1(s string) string {
    	b := []byte(s)
    	var reverse func(start, end int)
    	reverse = func(start, end int) {
    		for start < end {
    			b[start], b[end] = b[end], b[start]
    			start++
    			end--
    		}
    	}
    
    	reverse(0, len(b)-1)
    	start := 0
    	end := 0
    	i := 0
    	res := ""
    	for i < len(b) {
    		if b[i] != ' ' {
    			start = i
    			for i < len(b) && b[i] != ' ' {
    				i++
    			}
    			end = i - 1
    			reverse(start, end)
    			res = res + " " + string(b[start:end+1])
    		}
    		i++
    	}
    	return res[1:] // 头部为空格
    }
    
  • 相关阅读:
    [leedcode 46] Permutations
    [leedcode 45] Jump Game II
    [leedcode 43] Multiply Strings
    [leedcode 42] Trapping Rain Water
    [leedcode 41] First Missing Positive
    [leedcode 40] Combination Sum II
    全排列
    [leedcode 39] Combination Sum
    [leedcode 38] Count and Say
    调和级数求和(分块)
  • 原文地址:https://www.cnblogs.com/davis12/p/15464111.html
Copyright © 2011-2022 走看看