Python data structure to achieve (a)
- A: Array
- 1. General characteristics sequential storage structure of linear form:
- 2. python achieve dynamic array support expansion
- 3.python achieve an orderly array of fixed capacity
- 4. python achieve two ordered arrays into an ordered array
- 5. leetcode related exercises
- II: list
- 1. single-linked list in python
- 2. To achieve circulation single linked list in python
- 3. The two-way circular list with python
- 4. python inverted single-chain
- 5. python achieve two ordered lists merged into a sorted linked list
- 6. python intermediate node seeking to achieve the list
- 7.LeetCode exercises
A: Array
1. General characteristics sequential storage structure of linear form:
- Support random access
- Occupy contiguous storage space, the length of the immutable
python does not have an array structure, the array can be done while listing the basic function, it can also be achieved by nesting a multidimensional list, but when a large amount of data, will be slower. Usually we can use the array module or Numpy in the package array () creates an array.
2. python achieve dynamic array support expansion
Here, an array-based implementation to create a dynamic list of Python.
class DynamicArr:
def __init__(self, capacity=20):
'''
构造函数
:param capacity:数组容量大小,默认为20
'''
self._capacity = capacity
self._length = 0 # 数组的有效长度
# 基于列表实现,通过赋值None实现底层具有连续的内存空间,容量固定的数组
self._data = [None] * self._capacity
def __getitem__(self, index):
'''使得DynamicArr类实例化对象支持索引随机访问'''
return self._data[index]
def __setitem__(self, index, value):
'''使得DynamicArr类实例化对象支持直接赋值'''
self._data[index] = value
def getLength(self):
'''返回当前数组长度'''
return self._length
def getCapacity(self):
'''返回数组容量'''
return self._capacity
def add(self, index, value):
'''
往数组增加一个元素
:param index:待添加元素在数组的目标下标
:param value:待添加元素的值
'''
if index < 0 or index > self._length: # 无效的插入位置
raise Exception('invaild index: require 0 <= index <= self._size')
if self._length == self._capacity: # 数组已满
# 将数组容量扩充至两倍,比单独扩充一个单位要好,均摊复杂度为O(1)
self._resize(self._capacity*2)
for i in range(self._size, index-1, -1):
self._data[i+1] = self._data[i]
self._data[index] = value
self._length += 1
def addLast(self, value): # 往数组的末尾添加元素
return self.add(self._length, value)
def _resize(self, newCapacity):
'''
重构数组的容量
:param newCapacity:新的容量大小
'''
newArr = DynamicArr(newCapacity)
for i in range(self._length):
newArr.addLast(self._data[i])
self._capacity = newArr._capacity
self._data = newArr._data
3.python achieve an orderly array of fixed capacity
class StaticOrderArr:
def __init__(self, capacity=20): # 数组默认容量为20
self._capacity = capacity
self._length = 0
self._data = [None] * self._capacity
def __getitem__(self, index):
return self._data[index]
def __setitem__(self, index, value):
'''使数组支持更改操作'''
if index <= self._length and index >= 0:
if index == 0 or index == self._length-1:
self._data[index] = value
else:
if self._data[index-1] <= value and self._data[index+1] >= value:
self._data[index] = value
else:
raise Exception('set failed: require value meets the demand of order')
else:
raise Exception('set failed: invaild index')
def add(self, value):
'''
往有序数组添加值为value的元素
'''
if self._length == self._capacity:
raise Exception('The arrary is full')
elif self._length == 0:
self._data[0] = value
self._length += 1
else:
for i in range(self._length-1, -1, -1):
if self._data[i] > value:
self._data[i+1] = self._data[i]
else:
self._data[i+1] = value
self._length += 1
break
if self._data[0] > value:
self._data[0] = value
self._length += 1
def remove(self, index):
'''删除有序数组中下标为index的元素'''
if self._length == 0:
raise Exception('remove failed: Array is empty')
if index < 0 or index > self._length:
raise Exception('invaild index,require 0 <= index <= self._length')
else:
for i in range(index+1,self._length,1):
self._data[i-1] = self._data[i]
self._length -= 1
def getLength(self):
return self._length
def getCapacity(self):
return self._capacity
4. python achieve two ordered arrays into an ordered array
def isorder(arr=[]):
'''
判断数组是否有序
'''
arrSize = len(arr)
flag = True
if not arr:
flag = True
else:
for i in range(arrSize-1):
if arr[i] < arr[i+1]:
pass
else:
flag = False
return flag
def mergeSort(arr1=[],arr2=[]):
newArr = []
if isorder(arr1) and isorder(arr2): # 判断参数的合理性
if not arr1: # 当参数存在空数组的情况
newArr = arr2
elif not arr2:
newArr = arr1
else: # 当参数为两个有序数组的情况
i = j = 0
len1 = len(arr1);len2 = len(arr2)
while i < len1 and j < len2:
'''循环比较两个数组之间相对位置的元素大小,将较小的元素放入到新的数组中,直到有一组排序完毕'''
if arr1[i] <= arr2[j]:
newArr.append(arr1[i])
i += 1
else:
newArr.append(arr2[j])
j += 1
while i < len1: # 当arr1没有排序完毕
newArr.append(arr1[i])
i += 1
while j < len2: # 当arr2没有排序完毕
newArr.append(arr2[j])
j += 1
return newArr
else:
print('待排序的数组要求必须有序!')
5. leetcode related exercises
(1). Two numbers (1)
Implemented a hash table thinking:
class Solution:
def twoSum(self, nums, target):
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]
s = Solution()
s.twoSum([1,3,5,8,2,-1],10)
(2). Happy Number(202)
Implemented a hash table idea: When a value of the second time, then entered the loop, then you can directly determine the number of the number is not happy
class Solution:
def isHappy(self, n):
hash_set = dict()
while True:
if hash_set.get(n) == None:
hash_set[n] = 1
num = str(n)
length = len(num)
n = 0
for i in range(length):
n += int(num[i]) ** 2
if n == 1:
flag = True
break
else:
num = n
else:
flag = False
break
return flag
(3). Three Sum (seek and the number of three)
It is used in the idea: iterate ARR, and then the target - arr [i] and the solving method using two numbers, the arr [i] list of two numbers returned by the function [n1, n2] can be composed of a the solver.
def twoSum(nums, target):
hash_table = dict()
length = len(nums)
result = []
for i in range(length):
if hash_table.get(target - nums[i]) == None:
hash_table[nums[i]] = True
else:
result.append([target - nums[i], nums[i]])
return result
def threeSum(nums, target):
length = len(nums)
hash_table = dict()
result = []
for i in range(length):
target2 = target - nums[i]
if hash_table.get(nums[i]) == None:
hash_table[nums[i]] = True
temps = twoSum(nums[:i] + nums[i+1:], target2)
if temps:
for temp in temps:
temp.append(nums[i])
result.append(temp)
result_final = [list(t) for t in set(tuple(_) for _ in result)]
return result_final
(4). Majority Element (ask the mode)
Ideas: direct traversal, the first element to make initial comparison of the number, set up a counter count, the initial one. Through the array, when faced with the same value +1 or -1 encounter different value, when the count is zero, this will be compared to the number of array elements.
class Solution:
def majorityElement(self, nums: List[int]) -> int:
length = len(nums)
count = 1
comp = nums[0]
for i in range(1,length):
if nums[i] == comp:
count += 1
else:
count -= 1
if count == 0:
comp = nums[i]
count = 1
return comp
(5). Missing Positive (Lack seeking a positive number)
Using ideas: the idea of using the hash, through the array of elements greater than zero which the hash. After traversing the array, starting at 1 traverse the hash table, did not encounter the first value is the first visited a positive number asked for the missing
def firstMissingPositive(nums):
hash_table = dict()
maxPostive = -1
if not nums: # 数组为空
return 1
for num in nums:
if num >= 0 and hash_table.get(num) == None:
hash_table[num] = True
if maxPostive < num:
maxPostive = num
if maxPostive == -1: # 数组中没有正数
return 1
for i in range(1, maxPostive+2): # maxPostive+2 : 当所求最小正整数为数组中最大正数+1时
if hash_table.get(i) != True:
return i
II: list
1. single-linked list in python
class linkedList:
def __init__(self, data, pnext=None):
self.data = data
self.next = pnext
# 打印链表
def show(node):
p = node
while p:
print(p.data, end = ' ')
p = p.next
print('\n')
# 创建一个单链表
def createLinkedlist(lst=[]):
linkedlst = linkedList(lst[0])
head = linkedlst
p = head
for _ in lst[1:]:
node = linkedList(_)
p.next = node
p = node
return head
# 在链表index处的结点后插入值为value的结点
def insert(index, head, value):
count = 0
p = head
while p != None:
if count == index:
break
else:
p = p.next
count += 1
node = linkedList(value)
node.next = p.next
p.next = node
# 删除链表中所有值为value的结点
def delete(head, value):
while head.data == value: # 当头结点的值为value
head = head.next
pre = head
q = pre.next
while q != None:
if q.data == value:
pre.next = q.next
q = q.next
else:
pre = q
q = q.next
return head
2. To achieve circulation single linked list in python
class Recylelinkedlist:
'''不带头结点的单循环链表'''
def __init__(self, value, pnext=None):
self.next = pnext
self.data = value
# 创建一个带头结点单链表
def createRecyLinkedlist(lst=[]):
recylinkedlst = Recylelinkedlist(lst[0])
head = recylinkedlst
p = head
for _ in lst[1:-1]:
node = Recylelinkedlist(_)
p.next = node
p = node
node = Recylelinkedlist(lst[-1])
node.next = head
p.next = node
return head
def append(head, value):
'''
在尾结点后插入结点value
'''
p = head
while p.next != head: # 找到尾结点
p = p.next
node = Recylelinkedlist(value,head)
p.next = node
def pop(head):
'''删除单循环链表尾结点'''
p = head
while p.next.next != head:
p = p.next
p.next = head
def delFirst(head_node):
'''删除头结点'''
p = head_node
while p.next != head_node: # 找到尾结点
p = p.next
head = head_node.next
p.next = head
return head
# 在链表index处的结点后插入值为value的结点(若超过链表长度则继续循环往下数)
def insert(index, head, value):
r = head
count = 0
while count != index: # 找到index对应的结点
r = r.next
count += 1
if r.next == head: # 当目标位置刚好为尾结点位置
node = Recylelinkedlist(value,head)
r.next = node
else:
node = Recylelinkedlist(value)
node.next = r.next
r.next = node
# 删除链表中所有值为value的结点
def delete(head, value):
while True: # 若头结点的值为value
if head.data == value:
head = delFirst(head)
else:
break
pre = head
q = head.next
while q != head:
if q.data == value:
pre.next = q.next
q = q.next
else:
pre = q
q = q.next
return head
# 打印链表
def show(node):
p = node
while p.next != node:
print(p.data, end = ' ')
p = p.next
print(p.data) # 打印尾结点
print('\n')
lst = [13,41,4,1,41,5,6]
head = createRecyLinkedlist(lst)
show(head)
append(head,10)
show(head)
head = delFirst(head)
show(head)
pop(head)
show(head)
insert(2, head, 99)
show(head)
head = delete(head, 41)
show(head)
3. The two-way circular list with python
class DoubleRecylelinkedlist:
'''不带头结点的双向循环链表'''
def __init__(self, value, pnext=None, ppre=None):
self.next = pnext
self.pre = ppre
self.data = value
# 创建一个带头结点单链表
def createDoubleRecyLinkedlist(lst=[]):
doubleRecylinkedlst = DoubleRecylelinkedlist(lst[0])
head = doubleRecylinkedlst
p = head
for _ in lst[1:-1]:
node = DoubleRecylelinkedlist(_)
p.next = node
node.pre = p
p = node
node = DoubleRecylelinkedlist(lst[-1])
node.next = head
node.pre = p
p.next = node
head.pre = node
return head
def append(head, value):
'''
在尾结点后插入结点value
'''
p = head.pre # 尾结点
node = DoubleRecylelinkedlist(value)
p.next = node
node.pre = p
node.next = head
head.pre = node
def pop(head):
'''删除双循环链表尾结点'''
p = head.pre.pre
p.next = head
head.pre = p
def delFirst(head_node):
'''删除头结点'''
p = head_node.pre # 找到尾结点
head = head_node.next
head.pre = p
p.next = head
return head
# 在链表index处的结点后插入值为value的结点(若超过链表长度则继续循环往下数)
def insert(index, head, value):
r = head
count = 0
while count != index: # 找到index对应的结点
r = r.next
count += 1
if r.next == head: # 当目标位置刚好为尾结点位置
node = DoubleRecylelinkedlist(value)
r.next = node
node.pre = r
node.next = head
head.pre = node
else:
node = DoubleRecylelinkedlist(value)
node.next = r.next
r.next.pre = node
node.pre = r
r.next = node
# 删除链表中所有值为value的结点
def delete(head, value):
while True: # 若头结点的值为value
if head.data == value:
head = delFirst(head)
else:
break
pre = head
q = head.next
while q != head:
if q.data == value:
pre.next = q.next
q.next.pre = pre
q = q.next
else:
pre = q
q = q.next
return head
# 打印链表
def show(node):
p = node
while p.next != node:
print(p.data, end = ' ')
p = p.next
print(p.data) # 打印尾结点
print('\n')
lst = [13,41,4,1,41,5,6]
head = createDoubleRecyLinkedlist(lst)
show(head)
print(head.data,head.pre.data,head.next.data)
append(head,10)
show(head)
head = delFirst(head)
show(head)
pop(head)
show(head)
insert(2, head, 99)
show(head)
head = delete(head, 41)
show(head)
4. python inverted single-chain
def reversedLinklist(linkedlist):
r = linkedlist
p = r.next
r.next = None
q = p
p = p.next
while q != None:
q.next = r
r = q
q = p
if p != None:
p = p.next
return r
5. python achieve two ordered lists merged into a sorted linked list
def mergeSortLinkedlist(linkedlist1, linkedlist2):
'''两个有序的不带头结点的链表合并为一个不带头结点的有序链表'''
p = linkedlist1
q = linkedlist2
if q != None and p != None:
if p.data <= q.data:
head = p
p = p.next
head.next = None
else:
head = q
q = q.next
head.next = None
r = head # 创建头结点
while q != None and p != None:
if p.data <= q.data:
r.next = p
r = p
p = p.next
else:
r.next = q
r = q
q = q.next
if p: # 若linkedlist1没有排序结束
q = p
r.next = q
return head
6. python intermediate node seeking to achieve the list
def middleNode(linkedlist):
p = linkedlist
length = 0
while p != None:
length += 1
p = p.next
count = length // 2
p = linkedlist
while count:
p = p.next
count -= 1
return p
7.LeetCode exercises
(1). Linked List Cycle I (endless chain)
class Solution(object):
def hasCycle(self, head):
"""
:type head: ListNode
:rtype: bool
"""
if head:
while True:
if head.val == 'vncbasdnvnvmz':
return True
else:
head.val = 'vncbasdnvnvmz'
head = head.next
if head == None:
break
return False
(2). Merge k Sorted Lists (k merge sort list)
Adopted the idea: convert the list is the list, sort the list, and then create a list based on the list data
When execution: 116 ms, beat Merge k Sorted Lists of Python submission of 84.19% of user
memory consumption: 20.1 MB, defeated 11.89% of users of the Merge k Sorted Lists submitted in Python
class Solution(object):
def mergeKLists(self, lists):
"""
:type lists: List[ListNode]
:rtype: ListNode
"""
if lists:
re = []
for lst in lists:
if lst:
while lst:
re.append(lst.val)
lst = lst.next
if re:
re.sort()
head = ListNode(re[0])
r = head
for value in re[1:]:
node = ListNode(value)
r.next = node
return head