python data structure to achieve (a)

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

Guess you like

Origin blog.csdn.net/shichensuyu/article/details/90081395