力扣刷题|字符串(初级算法)

刷题链接:力扣

整数反转:

题目:给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。

如果反转后整数超过 32 位的有符号整数的范围 [−231,  231 − 1] ,就返回 0。

假设环境不允许存储 64 位整数(有符号或无符号)。

示例 1:

输入:x = 123
输出:321

算法思路:

python代码:因为是整数,所以把它变为单个的数字并且要翻转的话,思路就是处于10取余,然后这个余数再乘10加上下一个数就达到了翻转的效果,代码如下,但是有几个用例过不去,也不知道为什么。

参考代码里,把整数转为字符串了,然后通过切片反转。但是它的判断溢出那里,我就没太明白怎么会这样来判断???

python代码:

class Solution(object):
    def reverse(self, x):
        s = abs(x)
        res = 0
        while (s!= 0):
            if x > 0 and x > 2 ** 31 - 1: 
                return 0
            if x < 0 and x < (-2 ** 31 ):
                return 0
            temp = s % 10
            res = res * 10 + temp
            s = s / 10
        return res if x >= 0 else -res

class Solution(object):
    def reverse(self, x):
        s = str(abs(x))  # 取绝对值转字符串
        reverse_string = s[::-1]  # 反转字符串
        if len(reverse_string) > 1: # 如果数字大于一位数
            temp = int(reverse_string[:-1]) # 切去最后一位防止数字反转溢出
            print(temp)
            if temp > 2**31//10: # 溢出
                return 0
        return int(reverse_string) if x >= 0 else -int(reverse_string) 

字符串中的第一个唯一字符

题目:给定一个字符串 s ,找到 它的第一个不重复的字符,并返回它的索引 。如果不存在,则返回 -1 。

示例 :

输入: s = "loveleetcode"
输出: 2

算法思路:开始我在想要不要使用双指针,但是发现写不出来,然后借助count()这个查找个数的函数,一旦找到就return,但是这个代码会超出时间限制。

参考代码里用到了find()和rfind()函数,明天仔细弄清楚这两个函数。然后了解一下关于字符串的基础知识。

python代码:

class Solution(object):
    def firstUniqChar(self, s:str):
        for i in range(len(s)):
            if s.count(s[i])==1:
                return i
        return -1
            
s = "leetcode"
soluion = Solution()
firstUniqChar = soluion.firstUniqChar(s)
print(firstUniqChar)

#参考代码
class Solution(object):
    def firstUniqChar(self, s):
        # 先假设最小索引为最后的字符索引 + 1
        min_unique_char_index = len(s)

        # 已知字符串由小写字母构成,则遍历 a - z
        for c in "abcdefghizklmnopqrstuvwxyz":
            i = s.find(c)
            # 分别从目标的字符串头和字符串尾查找对应字母的索引;若两索引相等,则说明是单一字符
            if i != -1 and i == s.rfind(c):
                # 更新最小索引
                min_unique_char_index = min(min_unique_char_index, i)

        # 如果返回值不为最后字符的索引 + 1,则返回最小索引值
        # 否则,返回 -1
        return min_unique_char_index if min_unique_char_index != len(s) else -1

有效的字母异位词

题目:给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。

注意:若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词。

算法思路:

python代码:开始想的是暴力解法,但是没有写出来,然后看了别人的思路,使用了哈希表。如果没有defaultdict()函数,那么开始的时候dict_s和dict_t都是空字典,当第一次遇到s[i]时,它在字典中就还不存在所以就会找不到键‘s[i]’而引发KeyError,所以就需要defaultdict()函数当访问不存在的键时,会自动创建一个默认值。所以这里就使用了两个字典,它们的key是每一个字符,key对应的value是字符出现的个数。然后用出现在 dict_s 里面的k和v判断在dict_t这个字典里是不是也同样存在。

还有很直接的方法就是,对这两个字符串排序(sorted()函数),然后判断这两个字符串相不相等。

还有就是使用Counter()这个函数,它可以接受一个可迭代对象作为参数,并返回一个字典,其中键是元素,值是元素的出现次数。比如,print(s_count) 它的输出是:Counter({'a': 3, 'n': 1, 'g': 1, 'r': 1, 'm': 1})

python代码:

from collections import defaultdict
class Solution(object):
    def isAnagram(self,s,t):
        n = len(s)
        m = len(t)
        dict_s = defaultdict(int)
        dict_t = defaultdict(int)
        if n != m:
            return False
        for i in range(n):
            dict_s[s[i]] +=1
            dict_t[t[i]] +=1
        for k,v in dict_s.items():
            if dict_t[k] !=v:
                return False
        return True

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


class Solution(object):
    def isAnagram(self, s: str, t: str) -> bool:
        from collections import Counter
        a_count = Counter(s)
        b_count = Counter(t)
        return a_count == b_count

验证回文串

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

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

示例 1:

输入: s = "A man, a plan, a canal: Panama"
输出:true

算法思路:先都转为小写,然后移除所有非字母数字字符,之后反转看看是否和现在的相等?

python代码:

class Solution(object):
    def isPalindrome(self, s):
        if len(s)==0:
            return True
        t=[]
        s=s.lower()
        for i in s:
            if (ord(i)>=97 and ord(i)<=122) or (ord(i)>=48 and ord(i)<=57):
                t.append(i)
        if t==t[::-1]:
            return True
        else:
            return False
        

字符串转换整数 (atoi)

请你来实现一个 myAtoi(string s) 函数,使其能将字符串转换成一个 32 位有符号整数。

函数 myAtoi(string s) 的算法如下:

  • 空格:读入字符串并丢弃无用的前导空格(" ")
  • 符号:检查下一个字符(假设还未到字符末尾)为 '-' 还是 '+'。如果两者都不存在,则假定结果为正。
  • 转换:通过跳过前置零来读取该整数,直到遇到非数字字符或到达字符串的结尾。如果没有读取数字,则结果为0。
  • 舍入:如果整数数超过 32 位有符号整数范围 [−231,  231 − 1] ,需要截断这个整数,使其保持在这个范围内。具体来说,小于 −231 的整数应该被舍入为 −231 ,大于 231 − 1 的整数应该被舍入为 231 − 1 。
  • 返回整数作为最终结果。

算法思路:

这个题注意需要补的理论知识有:s.lstrip()函数可以移除字符串s开头的空白字符(包括空格、制表符、换行符等),if not s 表示如果s字符串为空,因为上传的是字符串的形式,所以当用isdigit()函数判断出这个字符串是数字时,需要把它加到输出的里时,需要用到d *= 10  d += ord(i) - 48 这个代码,ord(i) - 48就可以把 i 转为数字的形式。还有就是最后整数的范围,这个就可以在返回的时候 return max(-2**31, min(sign * d,2**31-1)) 妙啊!!!虽然写出来就是按照要求来写的,但是还有有很多步骤不知道该咋处理。

python代码:

class Solution(object):
    def myAtoi(self,s):
        s = s.lstrip()
        if not s:
            return 0
        sign = -1 if s[0]=="-" else 1
        if sign == -1 or s[0] == "+":
            s = s[1:]
        d = 0
        for i in s:
            if i.isdigit():
                d *=10
                d +=ord(i)-48
            else:
                break 
        return max(-2**31, min(sign * d,2**31-1))

实现 strStr()

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

示例 1:

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

算法思路:

这个题主要是看needle在不在 haystack里,如果用直观的想法就是判断 haystack[i:i+n] == needle 然后再用一个for循环,如果找到就return i ,就可以找到第一个了。代码如下,但是这个题是典型的KMP算法。

什么是KMP算法呢?

python代码:

class Solution(object):
    def strStr(self,haystack, needle):
        m,n = len(haystack),len(needle)
        for i in range(m):
            if haystack[i:i+n] == needle:
                return i
        return -1

外观数列

题目:「外观数列」是一个数位字符串序列,由递归公式定义:

  • countAndSay(1) = "1"
  • countAndSay(n) 是 countAndSay(n-1) 的行程长度编码。

行程长度编码(RLE)是一种字符串压缩方法,其工作原理是通过将连续相同字符(重复两次或更多次)替换为字符重复次数(运行长度)和字符的串联。例如,要压缩字符串 "3322251" ,我们将 "33" 用 "23" 替换,将 "222" 用 "32" 替换,将 "5" 用 "15" 替换并将 "1" 用 "11" 替换。因此压缩后字符串变为 "23321511"。

给定一个整数 n ,返回 外观数列 的第 n 个元素。

示例 1:

输入:n = 4

输出:"1211"

解释:

countAndSay(1) = "1"

countAndSay(2) = "1" 的行程长度编码 = "11"

countAndSay(3) = "11" 的行程长度编码 = "21"

countAndSay(4) = "21" 的行程长度编码 = "1211"

算法思路:就是根据countAndSay(n-1)的值来算countAndSay(n)的行程长度编码,然后知道countAndSay(1) = "1",有点像数学中的递归法。怎么实现呢?(不知道)看答案吧。

首先如果输入的是n,那么就返回'1',然后通过递归调用self.countAndSay(n - 1)获取上一个状态的结果,并将其赋值给s。同时,n ==1也是递归的终止条件。最开始的时候,会遍历完self.countAndSay(n - 1),直到把n 遍历到1。然后把返回的 字符串1 赋值给s。所以经过self.countAndSay(n - 1)后,s=‘1’。然后开始使用双指针,这个递归没有看懂唉,后面的双指针感觉把输出打出来也不对。算了,背吧!!!

python代码:

class Solution(object):
    def countAndSay(self,n):
        if n == 1:
            return "1"
        s = self.countAndSay(n - 1)
        ans =''
        start,end = 0,0
        while end < len(s):
            while end < len(s) and s[start] == s[end]:
                end +=1
            ans += str(end-start) + s[start]
            start = end
        return ans

最长公共前缀

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

示例 1:

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

算法思路:

如何把输入的字符串组分割出来呢?strs = ["flower","flow","flight"] print(strs[0])输出的是flower。然后使用二维数组strs[i][j],只需要判断第一个字符串与剩下的字符串相等吗?如果相等就记录它的count,然后在返回的时候,返回pre[:count]。

python代码:

class Solution(object):
    def longestCommonPrefix(self,strs):
        if len(strs)==0: 
            return ""
        pre = strs[0]
        strs = strs[1:]
        for i in range(len(strs)):
            count = 0
            length = min(len(pre),len(strs[i]))
            for j in range(length):
                if strs[i][j] == pre[j]:
                    count +=1
                else:
                    break
            pre = pre[:count]
        return pre

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值