Pythonネギブラシの質問07 - 文字列を反転&スペースを置換&文字列を左回転

344. 文字列を反転する

トピックへのリンク: https://leetcode.cn/problems/reverse-string/

タイトルの説明: 入力文字列を反転する関数を作成します。入力文字列は、文字の char[] 配列として指定されます。

別の配列に余分なスペースを割り当てないでください。この問題を解決するには、O(1) の余分なスペースを使用して、入力配列をインプレースで変更する必要があります。

配列内のすべての文字が ASCII コード テーブルの印刷可能な文字であると想定できます。

ケース

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

達成する:

方法 1 :

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中每一个对应的位置

方法 2 : ダブル ポインター
初期化: 2 つのポインター l と r をリストの最初と最後の要素を指すように設定します
ステップ: s[l] と s[r] の対応する要素を交換し、ポインターの位置を更新します (l+=) 1、r-=1) 2 つのポインターが一致するまで
時間計算量: 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. 文字列を反転する II

トピックへのリンク: https://leetcode.cn/problems/reverse-string-ii/

タイトルの説明: 文字列 s と整数 k が与えられた場合、文字列の先頭から数えて 2k 文字が数えられるごとに、2k 文字の最初の k 文字を反転します。

残りの文字が k 未満の場合は、残りの文字をすべて反転します。

残りの文字が 2k 未満で k 以上の場合、最初の k 文字を反転し、残りはそのままにしておきます。

ケース

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

達成する:

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. スペースを置き換える

トピックへのリンク: https://leetcode.cn/problems/ti-huan-kong-ge-lcof/

タイトルの説明: 文字列 s 内の各スペースを「%20」に置き換える関数を実装してください。

ケース

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

達成する:

方法 1 : トラバースと追加
Python や Java などの言語では、文字列は「不変」型として設計されています。つまり、文字列の文字を直接変更することはできず、それを実装するには新しい文字列を作成する必要があります。

アルゴリズム フロー:
リスト (Python) / StringBuilder (Java) を初期化し、res として記録します;
リスト内の各文字 c を走査します s:
c がスペースの場合: 文字列 "%20" を res に追加します;
c がそうでない場合スペースがある場合: res の後に文字 c を追加し、
リスト res を文字列に変換して返します。
複雑さの分析:
時間計算量 O(N)O(N)O(N): トラバーサルでは O(N)O(N)O(N) が使用され、文字の追加 (変更) 操作の各ラウンドでは O(1)O( 1) O(1);
スペースの複雑さ O(N)O(N)O(N): Python の新しいリストと Java の新しい StringBuilder は両方とも線形サイズの余分なスペースを使用します。

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)

方法2:ダブルポインタ方式

まず、各スペースを「%20」に置き換えた後のサイズに配列を拡張します。

次に、スペースを後ろから前に置き換える、つまりダブルポインター方式の場合、プロセスは次のとおりです。

i は新しい長さの終わりを指し、j は古い長さの終わりを指します。

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)

以前に完了したダブルポインタ ソリューション関連のトピックは次のとおりです。

27. 要素を削除する - Leetcode

15. 3 つの数字の合計 - Leetcode

18. 4 つの数字の合計 - Leetcode

206. 逆リンクリスト - Leetcode

142. リンクリスト II - Leetcode

344. 文字列を反転する - Leetcode

151. 文字列内の単語を反転する

トピックへのリンク: https://leetcode.cn/problems/reverse-words-in-a-string/

タイトルの説明: 文字列を指定してs、文字列内の単語の順序を逆にしてください。

単語は、空白文字以外の文字で構成される文字列です。文字列内の単語はs少なくとも 1 つのスペースで区切ります。

単語を反転し、単語を1 つのスペースで結合した結果の文字列を返します。

**注意:**s入力文字列内の単語の間には、先頭のスペース、末尾のスペース、または複数のスペースが存在する場合があります。返される結果文字列では、単語は 1 つのスペースでのみ区切られ、余分なスペースは含まれないようにしてください。

ケース

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

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

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

アイデア:

  • 余分なスペースを削除する
  • 文字列全体を反転します
  • それぞれの単語を反転させる

たとえば、ソース文字列は「空は青い」です。

  • 余分なスペースを削除します: 「空は青い」
  • 文字列の反転: "eulb si yks eht"
  • 言葉の反転:「ブルー・イズ・スカイ・ザ」

達成する:

方法 1:

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)  

方法2:ダブルポインタ方式

アルゴリズム分析:
文字列 sss を逆順にトラバースし、単語の左右のインデックス境界 iii、jjj を記録します。単語の
境界が決定されるたびに、それを単語リスト resres に追加します。
最後に、単語リストを次のように連結します。文字列を返します。
複雑さの分析:
時間計算量 O(N)O(N)O(N): NNN は文字列 sss の長さであり、文字列は線形に走査されます。
空間計算量 O(N)O(N)O(N): 新しく作成されたリスト (Python) または StringBuilder(Java) 内の文字列の合計長 (O(N)O(N を占める) ≤N\leq N ≤N) ) O(N) の余分なスペース。

問題解決のアイデアのソースへのリンク: 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)

Offer58-II を指す剣。文字列を左に回転

トピックへのリンク: https://leetcode.cn/problems/zuo-xuan-zhuan-zi-fu-chuan-lcof/

タイトルの説明: 文字列の左回転操作は、文字列の前のいくつかの文字を文字列の末尾に移動することです。文字列の左回転操作の機能を実現する関数を定義してください。たとえば、文字列「abcdefg」と数値 2 を入力すると、関数は 2 ビット左回転した結果「cdefgab」を返します。

ケース

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

達成する:

方法 1 : スライス

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

方法2:部分反転+全体反転

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)

方法 3 :

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

おすすめ

転載: blog.csdn.net/modi88/article/details/127750820