python百题大通关解题记录-数组与字符串

目录

002确定字符串是否是另一个的排列

 003确定字符串是否是另一个的旋转

005压缩字符串 

006找到给定字符串中的不同字符 

 007查找两个总和为特定值的索引


 本文题目编译自 Donne Martin 的开源项目

002确定字符串是否是另一个的排列

实现一个算法来识别一个字符串 str2 是否是另一个字符串 str1 的排列。排列的解释如下:

  • 如果将 str1 的字符拆分开,重新排列后再拼接起来,能够得到 str2 ,那么就说字符串 str2 是字符串 str1 的排列。

解:

本题初看想用全排列,再思发觉用sorted函数快速解决

sorted(str1)==sorted(str2)

sorted方法用来进行排序操作,如数字,字符串组成的list,根据dict类型的key或者value排序,现将平时使用的sorted的方法和数据类型进行整理。本题是罕见的直接对字符串排序 

 003确定字符串是否是另一个的旋转

实现一个算法来识别一个字符串 s2 是否是另一个字符串 s1 的旋转。旋转的解释如下:

  • 如果将 s1 从某个位置断开,拆分成两个字符串(可能有一个为空字符串),再将这两个字符串调换顺序后拼接起来,能够得到 s2 ,那么说字符串 s2 是字符串 s1 的旋转。

解: 

class Rotation(object):

    def is_substring(self, s1, s2):

        return s1 in s2

    def is_rotation(self, s1, s2):

        if s1 is None or s2 is None:
            return False
        if len(s1)!=len(s2):
            return False
        return self.is_substring(s1,s2+s2)

由于s2字符串旋转点的不确定性、子字符串判断函数is_substring()考虑到了有序性,巧妙地利用加倍延长证明全等(中学数学)的思想,对s2加倍,在长度判断后判断子字符串。 

005压缩字符串 

实现一个算法来压缩一个字符串。压缩的要求如下:

  • 需要判断压缩能不能节省空间,仅在压缩后字符串比原字符串长度更短时进行压缩。
  • 压缩的格式是将连续相同字符替换为字符+数字形式,例如 "AAABCCDDDD" 变为 "A3BC2D4"

解:(标答)

class CompressString(object):

    def compress(self, string):

        if string is None or not string:
            return string
        st_char=string[0]//当前压缩字符标志位
        count=0
        result=''
        for char in string:
            if char==st_char:
                count+=1
            else:
                result+=self.add(st_char,count)
                st_char=char//更换压缩字符
                count=1
        result+=self.add(st_char,count)
        return result if len(result)<len(string) else string//长度判断避免发生AA->A2的情况

    def add(self,st_char,count)://专用于返回压缩后的字符加数字
        return st_char+(str(count) if count>1 else '')

本题陷阱:压缩结果未必一定比原字符串短,只有更短才能输出,含有AA、AABB的双型字符串要警惕长度不变

006找到给定字符串中的不同字符 

在不考虑字符排列的条件下,对于相差只有一个字符的两个字符串,实现一个算法来识别相差的那个字符。要求如下:

  • 当传入的字符串为 'aad' 和 'ad' 时,结果为 'a'
  • 当传入的字符串为 'aaabccdd' 和 'abdcacade' 时,结果为 'e'

解:

第一种思路是字符数字化后,再字符化,利用差额转换

class Solution(object):

    def find_diff(self, str1, str2):

        if str1 is None or str2 is None:
            raise TypeError('str1 or str2 cannot be None')
        s1,s2=0,0
        for char in str1:
            s1+=ord(char)
        for char in str2:
            s2+=ord(char)
        return chr(abs(s1-s2))//仅相差一个字符,可以用Unicode编码转换数字化后再字母化

第二种思路是利用异或运算,出现两次的不影响结果,出现一次的留下痕迹 

class Solution(object):

    def find_diff(self, str1, str2):
        if str1 is None or str2 is None:
            raise TypeError('str1 or str2 cannot be None')
        result = 0
        for char in str1:
            result ^= ord(char)
        for char in str2:
            result ^= ord(char)
        return chr(result)

此外,raise TypeError('错误原因相关语句')使用较少 

 007查找两个总和为特定值的索引

给定一个数组,找到两个总和为特定值的索引。

  • 例如给定数组 [1, 2, 3, -2, 5, 7],给定总和 7,则返回索引 [1, 4]

解:(标答) 

        传统解法是双重遍历,复杂度过高。

        引入枚举enumerate,方便同时遍历索引和数值;引入字典,以差值为键存入当前索引(记作x),当遍历到差值时,可以直接取出x;这是以空间换时间的解法。

class Solution(object):

    def two_sum(self, nums, val):

        if nums is None or val is None:
            raise TypeError('Type is None')
        if len(nums)==0:
            raise ValueError('Value is not existed')
        lth=len(nums)
        dic={}
        for i,num in enumerate(nums)://使用枚举,更便捷地对索引和数值同时遍历
            res=val-num
            if num in dic:
                return [dic[num],i]
            else:
                dic[res]=i
        return None

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值