字符串专题

字符串循环移位包含

  1. 给定两个字符串s1和s2, 要求判定s2能否被s1做循环移位得到的字符串包含。: 只需判断s2是不是s1s1的子串。
    s1 = AABCD s2 = CDAA s1s1 = AABCDAABCD

字符串循环移位—GOOD

s = “1234ABCD” return “ABCD1234"上述是将s向右循环移动4位。
做法是将前四位和后面的单独翻转,得到"4321DCBA"然后再对整个字符串进行翻转,得到"ABCD1234”

字符串中单词的翻转

就是把每个单词依次翻转,再翻转一整个,就可以实现单词个体是正序的,但是整个句子里的单词顺序是翻转的。

242 有效的字母异位词

在这里插入图片描述

字母的异位词指的是出现的顺序不同,但是字母的数目必须都是相同的。
所以其实只要判断总数和各个字母的数目是否一样即可。

class Solution:
    def isAnagram(self, s: str, t: str) -> bool:

        # 字母异位指的是出现的顺序不同,但是字母数目都是相同的。
        if not t:
            return True

        if not s:
            return False

        if len(s) != len(t):
            return False

        dict = {}
        for i in s:
            if i not in dict:
                dict[i] = 1
            else:
                dict[i] += 1

        for i in t:
            if i in dict and dict[i] > 0:
                dict[i] -= 1
            else:
                return False

        for i in dict:
            if dict[i] > 0:
                return False

        return True

最长回文串

在这里插入图片描述
这道题出现了很多误区。:
首先,题意没有考虑清楚,虽然有的字母不是偶数,但是可以只取它的偶数部分!!!! 相当于取所有偶数和奇数的最大偶数部分,再加一。
这里除了哈希表也可以使用python自带的collections.Counter。

class Solution:
    def longestPalindrome(self, s: str) -> int:
        # 回文串是正读和反读都一样的字符串。
        if not s:
            return 0
        s_dict = {}
        for i in s:
            if i not in s_dict:
                s_dict[i] = 1
            else:
                s_dict[i] += 1
        length = 0
        add = 0
        for i in s_dict:
            length += s_dict[i] // 2 * 2
            if s_dict[i] % 2 != 0:
                add = 1
        return length + add

同构字符串

这里的同构指的是结构上是一样的。aabb和ccdd
想的一种思路是把两种英文字符串都用数字来表示,相当于 把中文和日文都翻译为英语,再对比是否相同。

在这里插入图片描述
这里要注意的是 是否在两个字典里都出现,都出现就判断是否相同;或者只出现一个的时候就是错的。

class Solution(object):
    def isIsomorphic(self, s, t):
        """
        :type s: str
        :type t: str
        :rtype: bool
        记录两个字符上次出现的位置,如果一样,说明是正确的"""
        if not s and not t:
            return True
        if not s or not t:
            return False

        dict1 = {}
        dict2 = {}

        for i in range(len(t)):

            if s[i] in dict1 and t[i] in dict2:
                if dict1[s[i]] != dict2[t[i]]:
                    return False

            elif (s[i] in dict1 and t[i] not in dict2) or (t[i] in dict2 and s[i] not in dict1):
                return False

            dict1[s[i]] = i
            dict2[t[i]] = i

        return True

计数二进制子串

给定一个字符串 s,计算具有相同数量0和1的非空(连续)子字符串的数量,并且这些子字符串中的所有0和所有1都是组合在一起的。
重复出现的子串要计算它们出现的次数。
在这里插入图片描述

其实不难,有点像上面的()的匹配。不用觉得01这种单个的匹配是障碍,其实并不会,多一个就加一而已。

时间复杂度是O(N), 空间是O(1)

class Solution:
    def countBinarySubstrings(self, s: str) -> int:
        if not s:
            return 0
        count = 0
        prev = 0
        now = 0
        for i in range(len(s)):  # 范围问题很重要,切勿漏掉第一个还是最后一个!!!!
            if i == 0:
                now += 1
                continue
            if s[i] != s[i - 1]:
                count += min(prev, now)
                prev = now
                now = 1
            else:
                now += 1

        count += min(prev, now)
        return count

时间复杂度O(n), 空间O(N)

class Solution(object):
    def countBinarySubstrings(self, s):
        """
        :type s: str
        :rtype: int
        """
        stack1 = []
        stack2 = []
        count = 0
        if not s:
            return 0
        for i in range(len(s)):
            if not stack1:
                stack1.append(s[i])

            elif s[i] != stack1[-1]:
                stack2.append(s[i])
                count += 1
                if len(stack2) == len(stack1):
                    stack1 = stack2
                    stack2 = []  
   # 如果stack2是append那么stack1会增加,但是如果直接变[],不会一起变化

            elif stack2 and s[i] == stack1[-1]:
                stack1 = stack2
                stack2 = []
                stack2.append(s[i])
                count += 1
                if len(stack2) == len(stack1):
                    stack1 = stack2
                    stack2 = []  
            else:
                stack1.append(s[i])

        return count
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值