算法(2)-数据结构-字符串


本系列博文为leetcode-explore-learn子栏目学习笔记,如有不详之处,请参考leetcode官网:https://leetcode-cn.com/explore/learn/card/array-and-string/198/introduction-to-array/768/

1.简述

字符串是字符构成的数组。由于其子串在维持一定顺序的情况下才具有意义,所以有单独拎出来进行讨论的必要。

字符串一些常用的函数:
(1)比较函数,Python支持云算法重载,可以使用"=="来比较字符串。
(2)可修改性,在Python中字符串是一个不可改写的数组;一经定义只能访问字符串中的元素,而不能直接改变某个元素。在C++中字符串是可修改的。
(3)字符串连接,python 中支持两个字符串直接相加操作进行字符串连接

>>> q = "cyy"
>>> q
'cyy'
>>> q[0] = "d"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment

2.例题

2.1 最长公共前缀

编写一个函数来查找字符串数组中的最长公共前缀。如果公共前缀不存在,返回空字符串""

输入:strs = [“flower”,“flow”,“flight”]
输出:“fl”

思路:用一个win区存公用前缀,找最短的字符串,将其元素依次加入win中。判断剩余字符串是否有该前缀字符。

class Solution(object):
    def longestCommonPrefix(self, strs):
        """
        :type strs: List[str]
        :rtype: str
        """
        short_str = ""
        short_str_len = float("INF")
        for sub_str in strs:
            if len(sub_str) <= short_str_len:
                short_str = sub_str
                short_str_len = len(sub_str)
        i = 1
        while(i <= short_str_len):
            for sub_str in strs:
                if sub_str[:i] != short_str[:i]:
                    return short_str[:i-1]
            i += 1
        return short_str  

2.2 最长回文子串

给你一个字符串 s,找到 s 中最长的回文子串。如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。

输入:s = “babad”
输出:“bab”
解释:“aba” 同样是符合题意的答案。

class Solution(object):
    def longestPalindrome(self, s):
        """
        :type s: str
        :rtype: str
        """
        n = len(s)
        if n == 0:
            return ""
        res_str = s[0]
        # dp = [[False] * n] * n   同一块空间?    不太对
        dp = [[False] * n for _ in range(n)]   # 初始化方式也很重要
        for i in range(n):
            dp[i][i] = True
        for i in range(n-1, -1, -1):      # 填充dp数组的方向很重要
            for j in range(i+1, n):
                # 更新dp数组
                if j == i+1 and s[i] == s[j]:
                    dp[i][j] = True
                elif dp[i+1][j-1] and s[i] == s[j]:
                    dp[i][j] = True
                # print(i, j, dp[i][j], s[i]==s[i], dp[i+1][j-1])
                # 更新最长回文子串
                if dp[i][j] and len(res_str) < j - i + 1:
                    res_str = s[i:j+1]
        return res_str

2.3 二进制求和

给一个二进制字符串,返回他们的和,用二进制表示。
基本思想:
两个字符串诸位相加,设置一个符号位flag用于存储进位信息
难点边界条件的确定:char=int(a[i])+int(b[i])+flag,chat的可能取值:0,1,2,3
(1)i=[-1,-2,-l_min]遍历相加逐个元素至较短字符串遍历完成
(2) i=[-l_min-1,-l_min-2m,…,-l_max]:char=flag+int(a[i]),char的可能取值:0,1,2
(3)最后还需要检查是否有进位情况

class Solution(object):
    def addBinary(self, a, b):
        """
        :type a: str
        :type b: str
        :rtype: str
        """
        res=[]
        l_a=len(a)
        l_b=len(b)
        l_min=min(l_a,l_b)
        l_max=max(l_a,l_b)
        flag=0
        for i in range(-1,-l_min-1,-1):
            char=int(a[i])+int(b[i])+flag
            flag=0
            if char==0:
                res.append(0)
            elif char==1:
                res.append(1)
            elif char==2:
                res.append(0)
                flag=1
            else:
                res.append(1)
                flag=1
            
        print (res,flag)
        if l_a>l_b:
            for i in range(-l_min-1,-l_max-1,-1):
                #print(i,res,flag)
                char=flag+int(a[i])
                flag=0
                if char==0:
                    res.append(0)
                elif char==1:
                    res.append(1)
                elif char==2 :
                    res.append(0)
                    flag=1
        if l_a<l_b:
            #print(l_min,l_max)
            for i in range(-l_min-1,-l_max-1,-1):
                #print(i,flag,res)
                char=flag+int(b[i])
                flag=0
                if char==0:
                    res.append(0)
                elif char==1:
                    res.append(1)
                elif char==2:
                    res.append(0)
                    flag=1
        #print(res,flag)
        if flag==1:
            res.append(1)
        l_res=len(res)
        res_s=""
        for i in range(l_res-1,-1,-1):
            res_s+=str(res[i])
        return res_

2.4 实现strStr()

给定一个haystack字符串和一个needle字符串,在haystack字符串中找出needle字符串出现的第一个位置。如果不存在则返回0.

思路,遍历haystack字符串,找出needle字符串的第一个字符,然后依次往后找,直至所有都匹配上然后返回结果。

注意点:
(1)当needle是空时,如果返回-1(说明在一个字符串中找不到空字符串);如果返回0(说明haysta[0]开始的字符串匹配了空字符串)–c++语言中是这么定义的
(2)两个都为空时,返回0
(3)len(haystack)<len(needle)直接返回-1

class Solution(object):
    def strStr(self, haystack, needle):
        """
        :type haystack: str
        :type needle: str
        :rtype: int
        """
        l_s=len(haystack)
        l_n=len(needle)
        if l_n==0:
            return 0
        if l_s==0:
            return -1
        if l_s<l_n:
            return -1
        for i in range(l_s-l_n+1): # i:[0,1,...,l_s-l-n]
            for j in range(l_n): # i:[0,1,...,l_n-1]l-s-l_n
                #print(i,j)
                if  haystack[i+j]!=needle[j]:
                    break
                if j==l_n-1:
                    return i
        return -1
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值