美文网首页
leetcode刷题之字符串

leetcode刷题之字符串

作者: sk邵楷 | 来源:发表于2022-05-23 22:50 被阅读0次

    leetcode刷题,使用python

    1, 无重复字符的最长子串 —— 0003 字符串

    给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。

    示例 1:

    输入: s = "abcabcbb"
    输出: 3
    解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
    示例 2:

    输入: s = "bbbbb"
    输出: 1
    解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
    示例 3:

    输入: s = "pwwkew"
    输出: 3
    解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
    请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

    
    class Solution:
        def lengthOfLongestSubstring(self, s: str) -> int:
            # 哈希集合,记录每个字符是否出现过
            occ = set()
            n = len(s)
    
            # 右指针,初始值为 -1,相当于我们在字符串的左边界的左侧,还没有开始移动
            rk, ans = -1, 0
    
            for i in range(n):
                if i != 0:
                   # 左指针向右移动一格,移除一个字符
                   occ.remove(s[i-1])
                while rk + 1 < n and s[rk + 1] not in occ:
                    # 不断地移动右指针
                    occ.add(s[rk+1])
                    rk += 1
    
                # 第 i 到 rk 个字符是一个极长的无重复字符子串
                ans = max(ans, rk - i + 1)
            return ans
    
    s = Solution()
    print(s.lengthOfLongestSubstring("abcabcbb"))
    print(s.lengthOfLongestSubstring("aabaab!bb"))
    
    

    2, 最长回文子串—— 005字符串

    给你一个字符串 s,找到 s 中最长的回文子串。

    示例 1:

    输入:s = "babad"
    输出:"bab"
    解释:"aba" 同样是符合题意的答案。
    示例 2:

    输入:s = "cbbd"
    输出:"bb"

    class Solution:
        def longestPalindrome(self, s: str) -> str:
            n = len(s)
    
            if n < 2:
                return s
    
            max_len = 1
            begin = 0
            # dp[i][j] 表示 s[i..j] 是否是回文串
            dp = [[False] * n for _ in range(n)]
            for i in range(n):
                dp[i][i] = True
    
            # 递推开始
            # 先枚举子串长度
            for L in range(2, n+1):
                # 枚举左边界,左边界的上限设置可以宽松一些
                for i in range(n):
                    # 由 L 和 i 可以确定右边界,即 j - i + 1 = L 得
                    j = L + i -1
                    # 如果右边界越界,就可以退出当前循环
                    if j >= n:
                        break
                    if s[i] != s[j]:
                        dp[i][j] = False
                    else:
                        if j - i < 3:
                            dp[i][j] = True
                        else:
                            dp[i][j] = dp[i+1][j-1]
    
                    # 只要 dp[i][L] == true 成立,就表示子串 s[i..L] 是回文,此时记录回文长度和起始位置
                    if dp[i][j] and j-i+1 > max_len:
                        max_len = j - i + 1
                        begin = i
            return s[begin:begin + max_len]
    s = Solution()
    print(s.longestPalindrome("babad"))
    

    3, z字形变换——0006 字符串
    将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。
    比如输入字符串为 "PAYPALISHIRING" 行数为 3 时,排列如下:
    P A H N
    A P L S I I G
    Y I R
    之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"PAHNAPLSIIGYIR"。
    示例 1:

    输入:s = "PAYPALISHIRING", numRows = 3
    输出:"PAHNAPLSIIGYIR"
    示例 2:
    输入:s = "PAYPALISHIRING", numRows = 4
    输出:"PINALSIGYAHRPI"
    解释:
    P I N
    A L S I G
    Y A H R
    P I
    示例 3:

    输入:s = "A", numRows = 1
    输出:"A"

    class Solution:
        def convert(self, s: str, numRows: int) -> str:
            n, r = len(s), numRows
            if r == 1 or r >= n:
                return s
    
            t = r * 2 - 2
            c = (n + t - 1) // t * (r - 1)
            mat = [[''] * c for _ in range(r)]
            x, y = 0, 0
            for i, ch in enumerate(s):
                mat[x][y] = ch
                if i % t < r - 1:
                    x += 1 # 向下移动
                else:
                    x -= 1
                    y += 1 # 向右上移动
    
            return ''.join(ch for row in mat for ch in row if ch)
    
    s = Solution()
    ss = "PAYPALISHIRING"
    numRows = 3
    print(s.convert(ss, 3))
    
    

    相关文章

      网友评论

          本文标题:leetcode刷题之字符串

          本文链接:https://www.haomeiwen.com/subject/ijhzurtx.html