【leetcode系列-数据结构专题-字符串】字符串中的第一个唯一字符/ 有效的字母异位词/赎金信

题目看起来很简单,怎么做都能做出来,但重点在于【数据结构】,要学会灵活应用不同的数据类型和结构进行快速解题。这里总结几个官方的解法如下:

题目如下:

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

力扣https://leetcode-cn.com/problems/first-unique-character-in-a-string/

class Solution:
    def firstUniqChar(self, s: str) -> int:
        #法1:hash表,内置自带collection,按照元素从多到少顺序排列字典
        l=collections.Counter(s)
        for i,strs in enumerate(s):
            if l[strs]==1:
                return i 
        return -1
        #法2:自定义hash表,速度更快,空间更低
        #以值为key,位置为vlue储存
        #count按字母顺序存储
        count=dict()
        for i,strs in enumerate(s):
            #重复地方value=-1
            if strs in count:
                count[strs]=-1
            #不重复地方value=位置
            else:
                count[strs]=i
        #print(count)
        for value in count.values():
            #print(value)
            #检索并输出第一个value不为-1的值
            if value!=-1:
                return value
        return -1

2. 有效的字母异位词

力扣https://leetcode-cn.com/problems/valid-anagram/

class Solution:
    def isAnagram(self, s: str, t: str) -> bool:
        #法1:哈希表,快
        #if len(s)!=len(t):
        #    return False
        if collections.Counter(s)==collections.Counter(t):
            return True
        return False
        #法2:排序,ASCII码
        s=list(s)
        t=list(t)
        s.sort()
        t.sort()
        if s==t:
            return True
        else:
            return False

3.赎金信

力扣https://leetcode-cn.com/problems/ransom-note/

class Solution:
    #法1:哈希表,字典减法
    def canConstruct(self, ransomNote: str, magazine: str) -> bool:
        #如果可以拼成,ransomNote中字符肯定包含于magazine
        if len(ransomNote)>len(magazine):
            return False
        return not collections.Counter(ransomNote)-collections.Counter(magazine)
    #法2:这个很妙,将用过的字符“删除”,即用“ ”(空值)来替换
    class Solution:
    def canConstruct(self, ransomNote: str, magazine: str) -> bool:
        for i in range(len(ransomNote)):
            if ransomNote[i] in magazine:
                magazine = magazine.replace(ransomNote[i],'',1)
            else:
                return False
        return True
  

这里要提到replace的用法了:

str.replace(old, new, max(optional))

返回字符串中的 old(旧字符串) 替换成 new(新字符串)后生成的新字符串,如果指定第三个参数max,则替换不超过 max 次

示例:

#!/usr/bin/python
 
str = "this is string example....wow!!! this is really string";
print str.replace("is", "was");
print str.replace("is", "was", 3);

输出结果:

thwas was string example....wow!!! thwas was really string
thwas was string example....wow!!! thwas is really string(超过三次不再替换)

【有一点一定要注意!!】

 【replace 不会改变原 string 的内容!!因此如果需要更新,那么需要每次重新对string进行赋值!!】

举例:

temp_str = 'this is a test'
print(temp_str.replace('is','IS'))
print(temp_str)

结果:

thIS IS a test
this is a test

---------------------------------------------------------------------------------------------------------------------------------

整体来说,无外乎几种经典解法:

(1)效率最高的:哈希表hashtable,即字典解法,因为无序所以快。

        这几道题中很常用的一个python的内置函数:collections.Counter()

(2)字符串转数组 obj()?char?【待整理】涉及到字符与ASCII码的转换问题

(3)队列,这个还要研究研究,暂时没明白优势在哪

以及一些小的python知识点整理:

(1)【字典】类型也可以相加减,用collections.Counter(dict)实现,但结果会自动舍掉value值<=0的dict.items()

示例如下:

#加入有两个字典dict如下:

x = {'a': 1, 'b': 2, 'c': 3}
y = {'a': 3, 'b': 1, 'd': 5}

字典的相加减操作需要用到python内置函数class:collections.Counter([iterable-or-mapping])

# 相加操作
re_1 = Counter(x) + Counter(y)
print(re_1)

# 相减操作
re_2 = Counter(x) - Counter(y)
print(re_2)

输出结果如下:

Counter({'a': 4, 'b': 3, 'c': 3, 'd': 5})
Counter({'b': 1, 'c': 3})

【在结果中,a不见了,是因为输出会忽略掉结果为零或者小于零的计数。】 

如果对Counter其它内容有兴趣的,可以查看下面的参考链接。
参考链接:Python Counter

(2)not 用法,除了传统的not 1(True)=False,not 0(False)=True外,空列表[] 字典dict()(字典一般不能为空,这里可以用defaultdict()/collections.Counter(dict)中,为空时返回默认值) 数组[]等都为False 可以用not判断

举例 not []=true

感谢参考:

(135条消息) Python字典加减操作_CoderRalfa的博客-CSDN博客_python 字典相减icon-default.png?t=M4ADhttps://blog.csdn.net/Ralfa17/article/details/110818478

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值