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