coding练习入门题目-使用python语言-由易到难,梯度设置合理

不知道为啥整了一些入门题目,本来以为是排序类的题目,但是做下来看着都是字符串相关的,倒是和排序没有一丁点关系。
题目有难有易,也涉及了哈希表、动态规划相关的知识,不过都比较简单,相对还算容易理解。
个人觉得没有必要单独拎出来叫入门题目,叫字符串类型题目倒是挺合适的。
废话不说了,开始一个一个题目来攻克,并写出来攻克时的心路历程。

627. 最长回文串

给出一个包含大小写字母的字符串。求出由这些字母构成的最长的回文串的长度是多少。
数据是大小写敏感的,也就是说,“Aa” 并不会被认为是一个回文串。

class Solution:
    """
    @param s: a string which consists of lowercase or uppercase letters
    @return: the length of the longest palindromes that can be built
    """
    def longestPalindrome(self, s):
        # write your code here
        # 这个题目初看时没有理解,看了一会才明白不是要子串,类似于要子序列
        # 那就找出不能配对的字符有多少个,最长回文串的长度是减去不能配对字符的个数再加1
        # 怎么找出不能配对的字符有多少个还是有点技巧的,可以认真体会下代码
        if len(s) == 0:
            return 0
        hash = {}
        for c in s:
            if c in hash:
                del hash[c]
            else:
                hash[c] = True 
        remove = len(hash)
        if remove > 0:
            remove = remove - 1
        return len(s) - remove

二刷

思路、解法和一刷是一样。这个解法还是挺精巧的,不知道还有没有别的解法。

三刷,很有必要

class Solution:
    """
    @param s: a string which consists of lowercase or uppercase letters
    @return: the length of the longest palindromes that can be built
    """
    def longestPalindrome(self, s):
        # write your code here
        # 初看时没有思路,然后发现可以统计字符出现的次数
        # 但是仍然不知道具体怎么实现
        # 看了答案后,觉得思路非常精巧,但是难以想出来
        # 统计不能构成回文串的字符的数量
        # 但是这个解法确实不易被想出来
        # 接下来给一个比较直接的解法
        # 记录每个字符出现的次数,如果为偶数次,全部加到总长度
        # 如果为奇数次,加到总长度。这个时候总长度就变为奇数了
        # 后续的奇数次,就减去1,然后再加到总长度
        import collections
        count = collections.Counter(s)
        res = 0
        for val in count.values():
            if val % 2 == 0:
                res += val
            else:
                if res % 2 == 0:
                    res += val
                else:
                    res += (val - 1)

        return res 

13. 字符串查找

对于一个给定的 source 字符串和一个 target 字符串,你应该在 source 字符串中找出 target 字符串出现的第一个位置(从0开始)。如果不存在,则返回 -1。

class Solution:
    """
    @param source: 
    @param target: 
    @return: return the index
    """
    def strStr(self, source, target):
        # Write your code here
        # 这个题目帮我复习了字符串相关的知识,切片,比较,
        # find方法,upper方法,遍历,长度
        # version 1
        # 遍历source字符串,看是否存在字串和target相同
        # len_s = len(source)
        # len_t = len(target)
        # for i in range(len_s - len_t + 1):
        #     if source[i:i + len_t] == target:
        #         return i 
        # return -1

        # version 2
        # 使用字符串方法 find
        return source.find(target)

二刷

思路和解法和一刷一样

415. 有效回文串

给定一个字符串,判断其是否为一个回文串。只考虑字母和数字,忽略大小写。

class Solution:
    """
    @param s: A string
    @return: Whether the string is a valid palindrome
    """
    def isPalindrome(self, s):
        # write your code here
        # 首先是知晓回文串的定义,已知晓
        # 其次看清题目中说的只考虑字母和数字,忽略大小写
        # 帮我掌握字符串方法,isalnum()是否只含有字母或数字,isalpha()是否只含有字母,
        # isdigit()是否只含有数字,s.lower()转为小写字母
        # 使用两根指针从两边到中间遍历整个字符串,
        # 遇到不同的字符就表明不是回文串,返回false
        start = 0
        end = len(s) - 1
        s = s.lower()
        while start < end:
            if start < end and s[start].isalnum() and s[end].isalnum():
                if s[start] != s[end]:
                    return False
                start += 1
                end -= 1
            if start < end and not s[start].isalnum() and s[end].isalnum():
                start += 1
            if start < end and s[start].isalnum() and not s[end].isalnum():
                end -= 1
            if start < end and not s[start].isalnum() and not s[end].isalnum():
                start += 1
                end -= 1
        return True 

二刷,代码更简洁一些

class Solution:
    """
    @param s: A string
    @return: Whether the string is a valid palindrome
    """
    def isPalindrome(self, s):
        # write your code here
        # 不占用额外空间,
        # 采用双指针,一头一尾
        i, j = 0, len(s) - 1
        while i < j:
            while i < j and not s[i].isalnum():
                i += 1
            while i < j and not s[j].isalnum():
                j -= 1
            while i < j and s[i].lower() != s[j].lower():
                return False 

            i += 1
            j -= 1

        return True 

200. 最长回文子串

给出一个字符串(假设长度最长为1000),求出它的最长回文子串,你可以假定只有一个满足条件的最长回文串。

class Solution:
    """
    @param s: input string
    @return: a string as the longest palindromic substring
    """
    def longestPalindrome(self, s):
        # write your code here
        # 刚看到题目时感觉是动规题目,想用动规来做,但是没能实现
        # 答案采用的是基于中心线的枚举,感觉也非常好
        # 尝试用答案的解法自己实现一遍
        length = len(s)
        if length == 0:
            return ''
        longest = 0
        for i in range(length):
            sub = self.findPalindrome(s, i, i)
            if longest < len(sub):
                longest = len(sub)
                res = sub
            sub = self.findPalindrome(s, i, i + 1)
            if longest < len(sub):
                longest = len(sub)
                res = sub
        return res 
    def findPalindrome(self, s, left, right):
        while left >= 0 and right <= len(s) - 1:
            if s[left] != s[right]:
                break 
            left = left - 1
            right = right + 1
        return s[left + 1:right]

二刷,掌握的不够好

667. 最长的回文序列

给一字符串 s, 找出在 s 中的最长回文子序列的长度. 你可以假设 s 的最大长度为 1000.

class Solution:
    """
    @param s: the maximum length of s is 1000
    @return: the longest palindromic subsequence's length
    """
    def longestPalindromeSubseq(self, s):
        # write your code here
        # 这个题目看着和627 最长的回文串类似,但是实际上是不同的
        # 差异在于子序列的定义,子序列不同于子串,但也是不能改变字符次序的
        # 没说是不是大小写敏感,那就默认是敏感的
        # 不会做,看了答案后,觉得也挺简单的
        # dp[i][j]表示字符i到j的最长回文子序列
        # 如果首尾字符相同,dp[i][j]等于去掉首尾字符后的字符串的最长回文子序列加2
        # 如果首尾字符不同,dp[i][j]等于
        # 去掉首字符的字符串的最长回文子序列和去掉尾字符的字符串的最长回文子序列的较大值
        
        length = len(s)
        if length == 0:
            return 0
        dp = [[0] * length for _ in range(length)]
        for i in range(length - 1, -1, -1):
            dp[i][i] = 1
            for j in range(i + 1, length):
                if s[i] == s[j]:
                    dp[i][j] = dp[i + 1][j - 1] + 2
                if s[i] != s[j]:
                    dp[i][j] = max(dp[i][j - 1], dp[i + 1][j])
        return dp[0][length - 1]

二刷,不会做

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值