数据结构与算法Python版之北大慕课笔记(一)
一、“变位词”判断问题
问题描述:变位词是指两个词之间存在组成字母的重新排列关系。如heart和earth,python和typhon。为了简单起见,假设参与判断的两个词仅由小写字母构成,且长度相等。
解题目标:写一个bool函数,以两个词作为参数,返回这两个词是否为变位词。
1. 解法一:逐字检查
解法思路:将词1中的字符逐个到词2检查是否存在,存在就打勾标记(防止重复检查),如果每个字符都能找到,则两个词是变位词,只要有一个字符找不到,就不是变位词。
程序技巧:实现打勾标记:将词2对应字符设为None,由于字符串是不可变类型,需要先复制到列表中。
代码实现:
# 解法一:逐字检查
def anangramSolution1(s1,s2):
alist = list(s2)
pos1 = 0
stillOK = True
while pos1 < len(s1) and stillOK:
pos2 = 0
found = False
while pos2 < len(alist) and not found:
if s1[pos1] == alist[pos2]:
found = True
else:
pos2 = pos2 + 1
if found:
alist[pos2] = None
else:
stillOK = False
pos1 = pos1 + 1
return stillOK
print(anangramSolution1('heart','earth'))
代码时间复杂度:总执行次数为:1+2+3+…+n ,故时间复杂度为:O(n²)
2. 解法二:排序比较
解法思路:将两个字符串都按照字母顺序排好序,再逐个字符对比是否相同,如果相同则是变位词,有任何不同则不是变位词。
代码实现:
# 解法二:排序比较
def anagramSolution2(s1,s2):
alist1 = list(s1)
alist2 = list(s2)
alist1.sort()
alist2.sort()
pos = 0
matches = True
while pos < len(s1) and matches:
if alist1[pos] == alist2[pos]:
pos = pos + 1
else:
matches = False
return matches
print(anagramSolution2('heart','earth'))
代码时间复杂度:本算法时间主导的步骤是排序步骤,所以时间复杂度就等于排序的时间复杂度:O(nlogn)
3. 解法三:计数比较
解法思路:对比两个词中每个字母出现的次数,如果26个字母出现次数都相同的话,这两个字符串就一定是变位词。
具体做法:为每个词设置一个26位计数器,先检查每个词,在计数器中设定好每个字母出现的次数。计数完成后,进入比较阶段,看两个字符串的计数器是否相同,如果相同则说明是变位词。
代码实现:
# 解法三:计数比较
def anagramSolution3(s1,s2):
c1 = [0] * 26
c2 = [0] * 26
for i in range(len(s1)):
pos = ord(s1[i]) - ord('a') # ord()返回一个字母的unicode编码
c1[pos] = c1[pos] + 1
for i in range(len(s2)):
pos = ord(s2[i]) - ord('a')
c2[pos] = c2[pos] + 1
j = 0
stillOK = True
while j < 26 and stillOK:
if c1[j] == c2[j]:
j = j + 1
else:
stillOK = False
return stillOK
print(anagramSolution3('heart','earth'))
代码时间复杂度:前两个循环用于对字符串进行计数,操作次数等于字符串长度n,第三个循环用于计数器比较,操作次数为26。所以该代码总操作次数为:2n+26,时间复杂度为:O(n)
注:该代码也采用了 “用空间换时间” 的思想。
二、线性结构linear structure
线性结构是一种有序数据项的集合,其中每个数据项都有唯一的前驱和后继。
- 除了第一个没有前驱,最后一个没有后继。
- 新的数据项加入到数据集中时,只会加入到原有某个数据项之前或之后。
- 具有这种性质的数据集,就称为线性结构。
1. 四个线性结构
- 栈 stack —— 后进先出(LIFO:last in first out)
- 队列 queue —— 先进先出(FIFO:first in first out)
- 双端队列 deque
- 列表 list
2. 栈的应用
2.1 括号匹配
from pythonds.basic.stack import Stack
def parChecker(symbolString):
s = Stack()
balanced = True
index = 0
while index < len(symbolString) and balanced:
symbol = symbolString[index]
if symbol == "(":
s.</