基础数据结构篇(下)Day3-4

学习网址:https://datawhalechina.github.io/leetcode-notes/#/ch03/index.md

如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。

字母和数字都属于字母数字字符。

给你一个字符串 s,如果它是 回文串 ,返回 true ;否则,返回 false 

示例 1:

输入: s = "A man, a plan, a canal: Panama"
输出:true
解释:"amanaplanacanalpanama" 是回文串。

示例 2:

输入:s = "race a car"
输出:false
解释:"raceacar" 不是回文串。

示例 3:

输入:s = " "
输出:true
解释:在移除非字母数字字符之后,s 是一个空字符串 "" 。
由于空字符串正着反着读都一样,所以是回文串。
class Solution(object):
    def isPalindrome(self, s):
        """
        :type s: str
        :rtype: bool
        """
        # 第一步:创建新字符串,去除字符串中的非字母数字字符
        new_s = ''
        # 遍历s中的每个字符
        for c in s:
            # 检测字符c是否为字母或数字
            if c.isalnum():
                # 如果是字母或数字,则添加到新字符串中
                new_s += c
        # 将过滤后的字符串赋值给s
        s = new_s
        
        # 第二步:将字符串转换为小写
        s = s.lower()
        
        # 第三步:使用双指针法判断回文
        # 初始化左指针left为0,右指针right为字符串长度减1
        left, right = 0, len(s) - 1
        
        # 当左指针小于右指针时,循环进行以下判断
        while left < right:
            # 如果左指针和右指针所指的字符不相等,则不是回文,返回False
            if s[left] != s[right]:
                return False
            # 如果相等,则左指针右移,右指针左移,继续比较下一对字符
            left += 1
            right -= 1
        
        # 如果循环结束都没有返回False,则说明字符串是回文,返回True
        return True

给定一个字符串 s ,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序。

示例 1:

输入:s = "Let's take LeetCode contest"
输出:"s'teL ekat edoCteeL tsetnoc"

示例 2:

输入: s = "Mr Ding"
输出:"rM gniD"

提示:

  • 1 <= s.length <= 5 * 104
  • s 包含可打印的 ASCII 字符。
  • s 不包含任何开头或结尾空格。
  • s 里 至少 有一个词。
  • s 中的所有单词都用一个空格隔开。
class Solution(object):
    def reverseString(self, s):
        """
        :type s: List[str]
        :rtype: None Do not return anything, modify s in-place instead.
        """
        # 反向输出数组即可
        s.reverse()

给定一个字符串 s ,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序。

示例 1:

输入:s = "Let's take LeetCode contest"
输出:"s'teL ekat edoCteeL tsetnoc"

示例 2:

输入: s = "Mr Ding"
输出:"rM gniD"

提示:

  • 1 <= s.length <= 5 * 104
  • s 包含可打印的 ASCII 字符。
  • s 不包含任何开头或结尾空格。
  • s 里 至少 有一个词。
  • s 中的所有单词都用一个空格隔开。

class Solution(object):
    def reverseWords(self, s):
        """
        :type s: str
        :rtype: str
        """
        # 输入:Mr Ding
        # 使用空格来分割每一个单词
        words = s.split(' ')
        # 输出:['Mr', 'Ding']

        # 反转每一个单词
        reversed_words = [word[::-1] for word in words]
        # 输出:['rM', 'gniD']

        # 将反转后的单词用空格连接起来
        return ' '.join(reversed_words)
        # 输出:rM gniD

给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标(下标从 0 开始)。如果 needle 不是 haystack 的一部分,则返回  -1 

示例 1:

输入:haystack = "sadbutsad", needle = "sad"
输出:0
解释:"sad" 在下标 0 和 6 处匹配。
第一个匹配项的下标是 0 ,所以返回 0 。

示例 2:

输入:haystack = "leetcode", needle = "leeto"
输出:-1
解释:"leeto" 没有在 "leetcode" 中出现,所以返回 -1 。

提示:

  • 1 <= haystack.length, needle.length <= 104
  • haystack 和 needle 仅由小写英文字符组成
  • 给定一个非空的字符串 s ,检查是否可以通过由它的一个子串重复多次构成。

    示例 1:

    输入: s = "abab"
    输出: true
    解释: 可由子串 "ab" 重复两次构成。
    

    示例 2:

    输入: s = "aba"
    输出: false
    

    示例 3:

    输入: s = "abcabcabcabc"
    输出: true
    解释: 可由子串 "abc" 重复四次构成。 (或子串 "abcabc" 重复两次构成。)
    

    提示:

  • 1 <= s.length <= 104
  • s 由小写英文字母组成
  • class Solution(object):
    
        def repeatedSubstringPattern(self, s):
    
            """
    
            :type s: str
    
            :rtype: bool
    
            """
    
            '''
    
            ,我们尝试将字符串 s 重复一次,然后去掉首尾各一个字符,看剩下的字符串是否包含原始字符串 s。如果包含,那么原始字符串 s 就是由它的一个子串重复多次构成的。
    
            '''
    
           
    
            # 将字符串 s 重复一次,然后去掉首尾各一个字符
    
            double_s = (s + s)[1:-1]
    
           
    
            # 检查剩下的字符串是否包含原始字符串 s
    
            return s in double_s

    给定一个非空的字符串 s ,检查是否可以通过由它的一个子串重复多次构成。

    示例 1:

    输入: s = "abab"
    输出: true
    解释: 可由子串 "ab" 重复两次构成。
    

    示例 2:

    输入: s = "aba"
    输出: false
    

    示例 3:

    输入: s = "abcabcabcabc"
    输出: true
    解释: 可由子串 "abc" 重复四次构成。 (或子串 "abcabc" 重复两次构成。)
    

    提示:

  • 1 <= s.length <= 104
  • s 由小写英文字母组成
class Solution(object):
    def repeatedSubstringPattern(self, s):
        """
        :type s: str
        :rtype: bool
        """
        '''
        ,我们尝试将字符串 s 重复一次,然后去掉首尾各一个字符,看剩下的字符串是否包含原始字符串 s。如果包含,那么原始字符串 s 就是由它的一个子串重复多次构成的。
        '''
        
        # 将字符串 s 重复一次,然后去掉首尾各一个字符
        double_s = (s + s)[1:-1]
        
        # 检查剩下的字符串是否包含原始字符串 s
        return s in double_s

给定两个字符串 a 和 b,寻找重复叠加字符串 a 的最小次数,使得字符串 b 成为叠加后的字符串 a 的子串,如果不存在则返回 -1

注意:字符串 "abc" 重复叠加 0 次是 "",重复叠加 1 次是 "abc",重复叠加 2 次是 "abcabc"

示例 1:

输入:a = "abcd", b = "cdabcdab"
输出:3
解释:a 重复叠加三遍后为 "abcdabcdabcd", 此时 b 是其子串。

示例 2:

输入:a = "a", b = "aa"
输出:2

示例 3:

输入:a = "a", b = "a"
输出:1

示例 4:

输入:a = "abc", b = "wxyz"
输出:-1
class Solution(object):
    def repeatedStringMatch(self, a, b):
        """
        :type a: str
        :type b: str
        :rtype: int
        """
        # 首先计算a重复叠加的次数,应该是b的长度除以a的长度的商
        times = len(b) // len(a)
        # 如果有余数,说明还需要再叠加一次
        if len(b) % len(a) != 0:
            times += 1
        # 生成a重复叠加times次的字符串
        combined_str = a * times
        # 检查b是否是combined_str的子串
        if b in combined_str:
            return times
        else:
            # 如果不是,再多叠加一次,再次检查
            combined_str += a
            if b in combined_str:
                return times + 1
            else:
                return -1

先读题,写注释分布完成,然后再想想注释里的步骤应该怎样实现。
暴力搜索(Brute Force)、拉宾-卡普(Rabin Karp)算法、Knuth-Morris-Pratt(KMP)算法后,每种算法都有其适用场景和优势。
暴力搜索直观易懂,但效率较低;Rabin-Karp利用滚动哈希提高多模式搜索效率;KMP算法通过预处理避免了回溯,高效地处理单模式匹配问题。

  • 14
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值