python数据结构实现(四)
1. 散列表
1.1 python实现一个基于链表法解决冲突问题的散列表
class ListNode:
def __init__(self, value, pnext=None):
self.data = value
self.next = pnext
class HashTable:
'''
选用除留余数法作为哈希函数
选用链地址法处理冲突,链表结构为带头结点的单链表
新插入的结点采用前插法,因为新插入的结点会更频繁地被访问
'''
def __init__(self, p):
'''
:param p: 哈希函数的除数
'''
self.array = [None] * p
self._div = p
def hashFun(self, key):
# 选用除留余数法作为哈希函数
return key % self._div
def insert(self, value):
'''
采用前插法将value作为结点插入到哈希表的链表中,
若当前链表不存在,则创建一个链表再继续插入该结点
:param value: 结点的值
'''
key = self.hashFun(value)
if self.array[key] is None:
self.array[key] = ListNode(None)
node = ListNode(value)
self.array[key].next = node
else:
node = ListNode(value)
node.next = self.array[key].next
self.array[key].next = node
def showTable(self):
for index in range(self._div):
if self.array[index]:
p = self.array[index].next
print('%d:' % index)
while p:
print(p.data,end='—>')
p = p.next
print('\n')
2.2 python实现一个 LRU 缓存淘汰算法
class ListNode:
def __init__(self, key=None, value=None, pnext=None, ppre=None):
self.key = key
self.value = value
self.next = pnext
self.pre = ppre
'''
使用哈希链表实现LRU算法
链表为带头结点的双向链表
链表尾结点为最近访问的结点
'''
class LruCache:
def __init__(self, capacity=5): # 缓冲区容量默认为5
self.cache = dict()
self.size = 0
self.capacity = capacity
self.head = ListNode()
self.end = self.head
def get(self, key):
node = self.cache.get(key)
if node is None:
return
else:
self._refreshNode(node)
return node.value
def put(self, key, value):
node = self.cache.get(key)
if node is None:
# 当该结点不存在于缓冲区,则加入缓冲区
self._addNode(key, value)
else:
# 当该结点存在于缓冲区,则更新结点和其在缓冲区的位置
node.value = value
self._refreshNode(node)
def remove(self, key):
node = self.cache.get(key)
if node is None:
return
else:
node.pre.next = node.next
node.next.pre = node.pre
self.size -= 1
def _addNode(self, key, value):
if self.capacity == self.size: # 若缓冲区容量已满,则删除头结点
self.head = self.head.next
# 将结点作为尾结点加入缓冲区
newNode = ListNode(key, value, ppre=self.end)
self.end.next = newNode
self.end = newNode
self.cache[key] = newNode
self.size += 1
def _refreshNode(self, node):
# 更新结点的位置
node.pre.next = node.next
node.next.pre = node.pre
self.end.next = node
node.pre = self.end
self.end = node
node.next = None
2. 字符串
2.1 python实现一个字符集,只包含 a~z 这 26 个英文字母的 Trie 树
class Trie:
def __init__(self):
"""
Initialize your data structure here.
"""
self.root = {}
self.end = -1 # 用于辅助识别该结点是否为单词的结尾
def insert(self, word: str) -> None:
"""
Inserts a word into the trie.
"""
curNode = self.root
for c in word:
if not c in curNode:
curNode[c] = {}
curNode = curNode[c]
curNode[self.end] = True
def search(self, word: str) -> bool:
"""
Returns if the word is in the trie.
"""
curNode = self.root
for c in word:
if not c in curNode:
return False
curNode = curNode[c]
if self.end in curNode:
return True
return False
def startsWith(self, prefix: str) -> bool:
"""
Returns if there is any word in the trie that starts with the given prefix.
"""
curNode = self.root
for c in prefix:
if not c in curNode:
return False
curNode = curNode[c]
return True
# Your Trie object will be instantiated and called as such:
# obj = Trie()
# obj.insert(word)
# param_2 = obj.search(word)
# param_3 = obj.startsWith(prefix)
2.2 python实现朴素的字符串匹配算法
def stringMatch(str1, str2):
'''
用朴素算法返回子串在主串中出现的第一次位置
:param str1: 主串
:param str2: 子串
:itype: str
:rtype: int
'''
i = j = 0; startPos = i
len1 = len(str1); len2 = len(str2)
flag = True; result = None
while flag:
i = startPos
while i < len1 and j < len2 and str1[i] == str2[j]:
i += 1; j += 1
if j == len2:
flag = False
result = startPos
else:
j = 0; startPos += 1
if i == len1:
flag = False
return result
3.LeetCode相关习题
3.1 两数之和
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
hash_dict = dict()
for i in range(len(nums)):
num = nums[i]
if hash_dict.get(target - num) == None:
hash_dict[num] = i
else:
return [hash_dict[target - num], i]
3.2 Reverse String (反转字符串)
class Solution:
def reverseString(self, s: List[str]) -> None:
"""
Do not return anything, modify s in-place instead.
"""
length = len(s)
i = 0; boundary = length // 2
while i < boundary:
s[i], s[length-1-i] = s[length-1-i], s[i]
i += 1
3.3 Reverse Words in a String(翻转字符串里的单词)
执行用时 : 48 ms, 在Reverse Words in a String的Python3提交中击败了95.24% 的用户
class Solution:
def reverseWords(self, s: str) -> str:
s = s.split(' ')
re = ''
s = s[::-1]
for n in s:
if n != '':
re = re + n + ' '
return re.strip()
3.4 String to Integer (atoi)(字符串转换整数 (atoi))
执行用时 : 60 ms, 在String to Integer (atoi)的Python3提交中击败了99.57% 的用户
内存消耗 : 12.9 MB, 在String to Integer (atoi)的Python3提交中击败了99.64% 的用户
def myAtoi(str):
str = str.lstrip()
str = str + ' '
re = ''; start = 0; sign = 1
numHash = dict.fromkeys('0123456789',True)
if str[0] == '+':
start += 1
elif str[0] == '-':
sign = -1; start += 1
for n in str[start:]:
if numHash.get(n) != None:
re += str[start]
start += 1
print(re)
elif re == '':
return 0
else:
re = sign * int(re)
print(re)
if re >= pow(2,31):
return 2147483647
elif re < -pow(2,31):
return -2147483648
return re