数据结构与算法(数组_栈_队列_链表_字符串)的实现和实践

前文

整理一下最近学的数据结构与算法的笔记。其实一直都有断断续续的学数据结构,但每次都是零碎的,这次想把之前学习的内容串起来,形成一个整体。

新年希望能把自己的学习路径记录下来,最好能整理成体系(给自己挖坑,不知道什么时候能填:)

适用人群:想学习数据结构与算法的coder们~


正文:

这篇文章整理的是下图标红的部分,本文会按照代码实现数据结构实践两部分,分别对数组,线性表,栈,队列,链表,字符串进行介绍,文中会包括python代码的实现。
在这里插入图片描述

1. 数组

1.1 数组的定义:
数组是具有一定顺序关系的若干对象组成的集合,组成数组的对象称为数组元素

1.2 静态数组和动态数组
静态数组,在程序编译时分配空间的数组(声明之后数组长度不可改变)。
动态数组,在程序运行时分配空间的数组(声明之后数组长度可根据问题而调整)

1.3 代码实现动态数组:

# 继承object和不继承object的区别,继承object会有更多的可操作对象(__XX__),这些都是类中的高级特性
class Arr:
    def __init__(self, capacity=10):
        """
        构造函数
        :param capacity:数组最大容量,不指定的话默认为10
        """
        self._capacity = capacity
        self._size = 0
        self._data = [None]*self._capacity

    def __getattr__(self, item):
        """让Arr类支持索引操作"""
        return self._data[item]

    def getSize(self):
        """返回数组有效元素个数"""
        return self._size

    def getCapacity(self):
        """返回当前容量"""
        return self._capacity

    def isEmpty(self):
        """判断当前数组是否为空"""
        return self._size ==0

    def add(self,index,elem):
        """
        向数组中添加元素
        :return:
        """
        if index < 0 or index > self._size: #输入的位置无效
            raise Exception('Add Filed. Require 0<= index <= self._size')
        if self._size==self._capacity: #容量满了
            # 默认扩容当前容量的二倍。容量翻倍要比容量加上一个固定值要好,这样做均摊复杂度为O(1)。具体请百度
            self._resize(self._capacity*2)

        #从尾部开始挪动元素,在index处腾出一个空间来
        for i in range(self._size-1,index-1,-1):
            self._data[i+1] = self._data=[i]
        self._data[index] = elem  #将该位置赋值为elem
        self._size +=1            #数组有效元素+1

    def addLast(self,elem):
        """
        向数组末尾添加元素
        :param elem: 所要添加的元素
        :return:
        """
        self.add(self._size,elem) # 直接调用add方法,注意不用再次判定合法性了,因为add函数中已经判断过了

    # private
    def _resize(self,new_capacity):
        """
        数组容量放缩至new_capacity,私有成员函数
        :param new_capacity:新的容量
        :return:
        """
        new_arr = Arr(new_capacity)#新建一个新的数组new_arr,容量为new_capacity
        for i in range(self._size):
            new_arr.addList(self._data[i]) #将当前数组的元素按当前顺序全部移动到new_arr中
        self._capacity = new_capacity # 数组容量变为new_capacity
        self._data = new_arr._data  #将new_arr._data赋值给self._data,从而完成数组的容量放大操作

    def addFirst(self,elem):
        """
        想数组头部添加元素
        时间复杂度:O(1)
        :param elem: 所有添加的元素
        :return:
        """
        self.add(0,elem)

    def get(self, index):
        """
        获得索引index处的元素
        时间复杂度:O(1)
        :param index: 数组索引
        :return:  索引处的值
        """
        if index<0 or index>=self._size:
            raise Exception("Get failed, Index is illegal.")
        return self._data[index]

    def getFirst(self):
        """
        获取数组首位元素的值
        :return: 首位置元素的值
        """
        return self.get(0)

    def getLat(self):
        """
        获取数组末尾元素的值
        :return:末尾元素的值
        """
        return self.get(self._size-1)

    def set(self,index,elem):
        """
        将索引为index的元素的值设为elem
        时间复杂度:O(1)、
        :param index:索引
        :param elem:新的值
        :return:
        """
        if index<0 or index>=self._size:
            raise Exception('Set Failed. Index is illegal.')
        self._data[index] = elem

    def contains(self,elem):
        """
        查看数组中是否存在元素elem,最好不要传入一个浮点数...
        时间复杂度:O(n)
        :param elem:目标元素
        :return:bool值,存在为真
        """
        for i in range(self._size):  # 遍历
            if self._data[i] == elem:
                return True       # 找到了就返回True
        return False              # 遍历完了还没找到,就返回False

    def find(self,elem):
        """
        在数组中查找元素,并返回元素所在的索引。(如果数组中存在有多个elem,只返回最左边elem的索引
        时间复杂度: O(n)
        :param elem:目标元素
        :return:  元素所在的索引,没找到则返回-1
        """
        for i in range(self._size):
            if self._data[i]==elem:
                return i
        return -1

    def findAll(self,elem):
        """
        找到值为elem全部元素索引
        :param elem: 目标元素
        :return: 一个列表,值全部elem的索引
        """
        ret_list = Arr()
        for i in range(self._size):
            if self._data[i]==elem:
                ret_list.addLast(i)
        return ret_list

    def remove(self,index):
        """
        删除索引为index的元素,index后面的元素都要向前移动一个位置
        时间复杂度O(n)
        :param index:目标索引
        :return:位于该索引的元素的值
        """
        if index < 0 or index >= self._size:
            raise Exception('Remove failed.Require 0<= index <self._size')
        ret = self._data[index]          # 拷贝一下index的位置,便于返回
        for i in range(index+1, self._size):
            self._data[i-1] = self._data[i]
        self._size -=1                  # 维护self._size
        self._data[self._size] = None   # 最后一个元素的垃圾回收
        return ret

    def removeFirst(self):
        """
        删除数组首位置的元素
        时间复杂度:O(n)
        :return:数组首位置的元素
        """
        return self.remove(0)

    def removeLast(self):
        """
        删除数组首位置的元素
        时间复杂度:O(n)
        :return:数组首位置的元素
        """
        return self.remove(self._size-1)   # 调用remove函数

    def removeElement(self,elem):
        """
        删除数组中卫elem的元素,如果数组中不存在elem,那么什么都不做,如果存在多个,只删除最左边的那个
        :param elem:要删除的值
        :return:
        """
        index = self.find(elem)
        if index!=-1:
            self.remove(index)

    def removeALLElement(self,elem):
        """
        删除数组内所有值为elem的元素,可以用递归来写,这里用迭代的方法,elem不存在就什么都不做
        :param elem: 要删除的目标元素
        :return:
        """
        while True:
            index = self.find(elem)
            if index != -1:
                self.remove(index)
            else:
                break

    def get_Max_index(self):
        """
        获取数组中的最大元素的索引,返回最大的索引值,如果有多个最大值,返回最左边的
        :return:
        """
        if self.isEmpty():
            raise Exception("Error, array is Empty!")
        max_elem_index = 0  #记录最大的索引,初始化为0
        for i in range(self.getSize()):
            if self._data[i]>self._data[max_elem_index]:
                max_elem_index= i
        return max_elem_index

    def get_Min_index(self):
        """
         获取数组中的最小元素的索引,返回最小元素的索引值,如果有多个最小值,默认返回最左边那个的索引
        时间复杂度:O(n)
        :return:  最小元素的索引
        """
        if self.isEmpty():
            raise Exception('Error, array isEmpty!')
        min_elem_index = 0 # 记录最小值得索引,初始化为0
        for i in range(1,self.getSize()):
            if self._data[i]<self._data[min_elem_index]:
                min_elem_index=i
        return min_elem_index

    def swap(self, index1, index2):
        """
        交换分别位于索引index1和索引index2处的元素
        :param index1: 索引1
        :param index2: 索引2
        """
        if index1 < 0 or index2 < 0 or index1 >= self._size or index2 >= self._size:        # 合法性检查
            raise Exception('Index is illegal')
        self._data[index1], self._data[index2] = self._data[index2], self._data[index1]

1.4 实践

  • task1:
    利用动态数组解决数据存放的问题,编写一段代码,要求输入一个整数N,用动态数组A来存放2-N之间所有5或者7的倍数,输出该数组

利用上面实现的数组class Arr

def put_five_seven(N):
    """
    输入一个整数N,返回被5或者7整除的数组
    :param self:
    :param N:
    :return: list
    """
    alist = Arr()
    for i in range(1,N+1):
        if i % 5 == 0 or i % 7 == 0:
            alist.addLast(i)
    return alist

if __name__=='__main__':
    N = input("请输入一个整数N=")
    target_list = put_five_seven(int(N))
    for i in range(target_list._size):
        print(target_list._data[i], " ")
  • task2:
    托普利茨矩阵问题,如果一个矩阵的每一方向由左上到右下的对角线上具有相同的元素,那么这个矩阵是拓普利茨矩阵
    1,2,3,4
    5,1,2,3
    9,5,1,2
    输入是一个包含整数的二维数组,行数和列数均在[1,20]范围内,整数包含在[0,99]范围内
    输出为true or false
def isToeplitzMatrix(matrix):
    """
    输入二维数组,判断是否为托普利茨矩阵(对角线元素一样)
    思路:如果位于(x,y)上的元素,只需要检查x==0 or c==0 or matrix[x][y] = matrix[x-1][y-1]
    :param matrix:
    :return:
    """
    # matrix[-1][-1]不会溢出,取的是最后一位数
    # all()表示所有都为true才返回true
    return all(r == 0 or c == 0 or matrix[r - 1][c - 1] == val for r, row in enumerate(matrix) for c, val in enumerate(row))

if __name__=='__main__':
    matrix = [[1, 2, 3, 4], [5, 1, 2, 3], [9, 5, 1, 2]]
    print(isToeplitzMatrix(matrix))

  • task3:
    三数之和:给定一个包含n个整数的数组nums,判断nums中是否存在三个元素a,b。c使得a+b+c=0?,找出所有满足条件且不重复的三元组
def sumOfThree(nums):
    nums.sort()  #排序
    res = []
    for i in range(len(nums)-2):
        if i > 0 and nums[i] == nums[i-1]:
            continue                #去重
        j = i+1                      #指针1
        k = len(nums)-1              #指针2
        while j < k:
            sums = nums[i]+nums[j]+nums[k]
            if sums == 0:
                res.append([nums[i], nums[j], nums[k]])
                while j < k and nums[j] == nums[j+1]: #去重
                    j += 1
                while j < k and nums[k] == nums[k-1]: #去重
                    k -= 1
                j += 1
                k -= 1
            elif sums < 0:
                j += 1
            else:
                k -= 1
    return res

if __name__=='__main__':
	nums=[-1,0,1,2,-1,-4]
    print(sumOfThree(nums))
2. 线性表

2.1 定义
线性表(Linear List)是由n(n >= 0)个相同类型的数据元素a1,a2,...,an 组成的有序序列。即表中除首尾元素外,其它元素有且仅有一个直接前驱和直接后继。首元素仅有一个直接后继,尾元素仅有一个直接前驱。表中数据元素的个数称为表的长度,记为:(a1,a2,...,an)

2.2 线性表的存储和实现
顺序存储(顺序表):利用顺序存储结构(即利用数组)实现的线性表。

链式存储(链表):利用指针方式实现的线性表称为链表(单链表、循环链表、双链表)。它不要求逻辑上相邻的数据元素在物理位置上也相邻,即:逻辑结构与物理结构可以相同也可以不相同。

2.3 代码实现

顺序存储结构实现线性表

# 顺序存储结构实现线性表
class SeqList(object):
    """
    线性表
    基本操作:
    """
    def __init__(self, maxsize):
        self.data = range(maxsize)
        self.maxsize = maxsize
        self.last = -1

    def __getitem__(self, key):
        """
        索引器
        :param item:
        :return:
        """
        if self.is_empty():
            print('SeqList is empty!')
            return
        elif key<0 or key>self.last:
            print("the given key is Error!")
        else:
            return self.data[key]

    def __setitem__(self, key, value):
        """
        索引器set
        :param key:
        :param value:
        :return:
        """
        if self.is_empty():
            print("SeqList is empty!")
            return
        if key <0 or key>self.last:
            print("the given key is Error!")
            return
        else:
            self.data[key] = value

    def __len__(self):
        """
        长度
        :return:
        """
        length = self.last + 1
        return length

    def getlengthe(self):
        """
        顺序表长度
        :return:
        """
        return self.last+1

    def clear(self):
        self.last=-1

    def is_empty(self):
        if self.last == -1:
            return True
        else: return False

    def is_full(self):
        """
        顺序表是否满了
        :return:
        """
        if self.last==self.maxsize-1:
            return True
        else:
            return False
    def insert(self,index,elem):
        """
        插入元素
        :param index:
        :param elem:
        :return:
        """
        if self.is_full():
            print('SeqList is full!')
            return
        elif index < 0 or index > self.last+1: # 当要插入的index没超过数组的最大容量时,index不能比最后一个index对应的值大1
            print("Position is error!")
            return
        elif index==self.last+1:
            self.last+=1
            self.data[self.last] = elem
        else:
            for i in range(self.last, index-1,-1):  # 原来的数据从index到last全部往后移一位
                self.data[i+1] = self.data[i]
            self.data[i] = elem   # 此时的i的值等于index
            self.last += 1

    def remove(self, index):
        """
        删除元素
        :param index:
        :return:
        """
        if self.is_empty():
            print('SeqList is empty!')
            return
        if index < 0 or index > self.last:
            print("Position is error!")
            return
        else:
            for i in range(index, self.last):
                self.data[i] = self.data[i+1]
            self.data[self.last] = None
            self.last-=1

    def find(self, data):
        """
        :param data:
        :return:存在返回该元素在线性表中的位置,否则返回-1
        """
        for i in range(self.last+1):
            if self.data[i] == data:
                return i

链式存储结构实现线性表
单向链表实现

# 定义节点类
class ListNode(object):
    def __init__(self, data):
        self.data = data
        self.next = None   # 指针

    def has_value(self,value):
        if self.data ==value:
            return True
        else:
            return False

# 定义单链表类
class SingleLinkedList():
    """
    __init__():初始化对象
    list_length():返回节点数量
    output_list():输出节点值
    add_list_item():在列表末尾增加一个新的节点
    unordered_search():根据一个特殊值去查询列表
    remove_list_item_by_id():根据节点id移除节点
    """
    def __init__(self):
        self.head = None  #头部
        self.tail = None

    def list_length(self):
        "return the number of list items"
        count = 0
        current_node = self.head
        while current_node is not None:
            count += 1
            current_node = current_node.next
        return count

    def output_list(self):
        """outputs the List"""
        current_node = self.head
        while current_node is not None:
            print(current_node.data)
            current_node = current_node.next

    def add_list_item(self, item):
        if not isinstance(item, ListNode):
            item = ListNode(item)
        if self.head is None:
            self.head = item
        else:
            self.tail.next = item
        self.tail = item

    def unordered_search(self, value):
        """根据一个特殊值去查询列表"""
        current_node = self.head
        node_id = 1
        results = []
        while current_node is not None:
            if current_node.has_value(value):
                results.append(node_id)
            current_node = current_node.next
            node_id = node_id + 1
        return results

    def remove_list_item_by_id(self, item_id):
        """根据结点索引删除"""
        current_id = 1
        current_node = self.head
        previous_node = None
        while current_node is not None:
            if current_id == item_id:
                if previous_node is not None:
                    previous_node.next = current_node.next
                else:
                    self.head = current_node.next
            previous_node = current_node
            current_node = current_node.next
            current_id = current_id + 1

双向链表实现

# 定义节点类
class ListNode1():
    def __init__(self,data):
        self.data = data
        self.next = None
        self.previous = None
    def has_value(self,value):
        if self.data ==value:
            return True
        else:
            return False
# 双向链表
class DoubleLinkedList():
    def __init__(self):
        """
        constructor to initiate this object
        """
        self.head = None
        self.tail = None

    def List_length(self):
        """return the number of list length"""
        count = 0
        current_node = self.head
        while current_node is not None:
            count +=1
            current_node = current_node.next
        return count

    def output_list(self):
        current_node = self.head
        while current_node is not None:
            print(current_node.data)
            current_node = current_node.next

    def unordered_search(self, value):
        """search the Linked List for the node that has this value"""
        current_node = self.head
        results = []
        node_id =1
        while current_node is not None:
            if current_node.has_value(value):
                results.append(node_id)
            current_node = current_node.next
            node_id = node_id + 1
        return results

    def add_list_item(self,item):
        """add an item at the end of the list"""
        if isinstance(item,ListNode):
            if self.head is None:
                self.head = item
                self.previous = None
                self.tail = item
            else:
                self.tail.next = item
                item.previous = self.tail
                self.tail = item

    def remove_list_item_by_id(self,item_id):
        current_node = self.head
        current_id = 1
        while current_node is not None:
            previous_node = current_node.previous
            next_node = current_node.next
            if current_id == item_id:
                # 分别判断id是否为头和链表是否只有一个元素
                if previous_node is not None:
                    previous_node.next = next_node
                    if next_node is not None:
                        next_node.previous = previous_node
                else:
                    self.head = next_node
                    if next_node is not None:
                        next_node.previous = None
            current_node = next_node
            current_id += 1

2.4 实践
task1:合并两个有序链表

class Solution():
    def merge_twoLinked_into_One(self,LinkA,LinkB):
        """
        1. 合并两个有序链表
        :param LinkA:
        :param LinkB:
        :return: 合并完后的链表
        """
        results = ListNode()
        current_nodeA = LinkA.head
        current_nodeB = LinkB.head
        while current_nodeA and current_nodeB is not None:
            if current_nodeA.data < current_nodeB.data:
                results.next = current_nodeA
                current_nodeA = current_nodeA.next
            else:
                results.next = current_nodeB
                current_nodeB = current_nodeB.next
        if current_nodeB is not None:
            results.next = current_nodeB
        if current_nodeA is not None:
            results.next = current_nodeA
        return results.next

task2:删除链表的倒数第N个节点

    def Delete_Reverse_N(self,track, n_id):
        """
        2. 删除链表的倒数第N个节点
        :param track: 链表
        :param n_id: 删除倒数第N个结点
        :return: 删除后的链表
        """
        length = track.list_length
        res = track.remove_list_item_by_id(length-n_id+1)
        return res

task3:反转链表

    def Reverse_Link(self,link):
        """
        3. 旋转链表
        :return:
        """
        if not link:
            return link
        p = link
        q = p.next
        p.next = None
        while q:
            r = q.next
            q.next = p
            p = q
            q = r
        return p
3. 栈

3.1 栈的定义
栈是线性表的一种,栈是插入(入栈)和删除(出栈)操作只能在一端(栈顶)进行的线性表。即先进后出(First In Last Out)的线性表。

3.2 栈的实现方式
栈有两种实现一种是顺序栈一种是链栈

3.3 代码实现
栈的顺序存储结构

class stack():
    """
    栈的顺序存储结构
    """
    def __init__(self, size):
        self.size = size
        self.stack = []
        self.top = -1

    def push(self,x):
        """
        入栈
        :param x:
        :return:
        """
        if self.is_full():
            raise Exception("stack is full!!!")
        else:
            self.stack.append(x)
            self.top = self.top + 1
    def pop(self):
        """
        出栈
        :return:
        """
        if self.is_empty():
            raise Exception("stack is empty!!!")
        else:
            self.top = self.top-1
            self.stack.pop()
    def is_full(self):
        """
        判断栈是否已满
        :return:
        """
        return self.top+1 == self.size
    def is_empty(self):
        """
        检查栈是否为空
        :return:
        """
        return self.top == -1
    def showStack(self):
        print(self.stack)

栈的链式存储结构

class Node(object):
    """
    栈的链式存储结构
    """
    def __init__(self,data=None):
        self.data = data
        self.next = None
class LinkStack(object):
    def __init__(self):
        self.top = Node(None)
        self.count = 0

    def get_legth(self):
        return self.count

    def get_top(self):
        """返回栈顶元素"""
        return self.top.data
    def is_empty(self):
        return self.count==0
    def push(self,elem):
        """进栈"""
        tmp = Node(elem)
        if self.is_empty():
            self.top = tmp
        else:
            tmp.next = self.top
            self.top = tmp
        self.count += 1

    def pop(self):
        """出栈"""
        if self.is_empty():
            raise IndexError("Stack is Empty!")
        else:
            self.count -=1
            elem = self.top.data
            self.top = self.top.next
            return elem
    def show_stack(self):
        """从栈顶开始显示各结点值"""
        if self.is_empty():
            raise IndexError("Stack is empty!")
        else:
            tmp = self.top
            j = self.count
            while tmp and j>0:
                print(tmp.data)
                tmp = tmp.next
                j -= 1

if __name__=="__main__":
    def test_linkStack():
        lks = LinkStack()
        for i in range(1, 5):
            lks.push(i)
        lks.show_stack()
        lks.pop()
        lks.show_stack()
    def test_stack():
        s = stack(10)
        for i in range(6):
            s.push(i)
        s.showStack()
        for i in range(3):
            s.pop()
        s.showStack()

4. 队列

4.1 队列的定义
队列和栈一样也是线性表的一种,队列是插入(入队)在一端(队尾)进行而删除(出队)在另一端(队首)进行的线性表。即先进先出(First In First Out)的线性表。

4.2 队列的存储方式
队列的存储方式同样分为顺序存储和链式存储。

4.3 代码实现
队列的顺序存储

class SqQueue():
    """队列的顺序存储"""
    def __init__(self, size):
        self.data = list(None for i in range(size+1))
        self.maxsize = size + 1
        self.front = 0
        self.rear = 0
        self.length = 0

    def get_length(self):
        return self.length

    def is_full(self):
        return (self.rear+1) % self.maxsize == self.front

    def is_empty(self):
        return self.rear == self.front

    def enQueue(self, elem):
        """
        进队列,从队尾加入
        :param elem:
        :return:
        """
        if self.is_full():
            raise IndexError("Queue is full!!!")
        else:
            self.data[self.rear] = elem
            self.rear = (self.rear + 1) % self.maxsize   # [0,1,2,None]
            self.length += 1
    def deQueue(self):
        """出队列,从对首删除"""
        if self.is_empty():
            raise ValueError("SqQueue is empty!")
        else:
            del_elem = self.data[self.front]
            self.data[self.front] = None
            self.front = (self.front + 1) % self.maxsize
            self.length -= 1
            return del_elem

    def show_queue(self):
        # 显示队列元素,从队首开始显示
        if self.is_empty():
            raise ValueError("SqQueue is empty!")
        else:
            j = self.front
            while j != self.rear:
                print(self.data[j])
                j = (j+1) % self.maxsize
            print(' ')

队列的链式存储结构

class Node():
    def __init__(self, data=None):
        self.data = data
        self.next = None

class LinkQueue():
    def __init__(self):
        self.front = Node()
        self.rear = Node()
        self.length = 0

    def get_length(self):
        return self.length

    def is_empty(self):
        return self.length == 0

    def enQueue(self, elem):
        tmp = Node(elem)
        if self.is_empty():
            self.rear = tmp
            self.front = tmp
        else:
            self.rear.next = tmp
            self.rear = tmp
        self.length += 1

    def deQueue(self):
        # 出队
        if self.is_empty():
            raise ValueError("LinkQueue is empty!")
        else:
            del_elem = self.front.data
            self.front = self.front.next
        self.length -= 1
        return del_elem

    def showQueue(self):
        if self.is_empty():
            raise ValueError("LinkQueue is empty!")
        j = self.length
        tmp = self.front
        while j>0:
            print(tmp.data)
            tmp = tmp.next
            j -= 1
        print(" ")

if __name__ == "__main__":
    def check_listQueue():
        sqq = SqQueue(5)
        for i in range(5):
            sqq.enQueue(i)
        sqq.show_queue()
        print("---------------------")
        sqq.deQueue()
        sqq.show_queue()

    def check_LinkQueue():
        lkq = LinkQueue()
        for i in range(5):
            lkq.enQueue(i)
        lkq.showQueue()
        print(";;;;;;;;;;;;;;;")
        lkq.deQueue()
        lkq.showQueue()
    check_LinkQueue()

4.4 队列的实践

模拟银行大厅叫号服务程序

from DataWhale.Queue_task04 import LinkQueue
# from DataWhale.Queue_task04 import Node
import threading
import time
class LinkBankQueue(LinkQueue):
    def __init__(self):
        LinkQueue.__init__(self)
        self.callnumber = 0

    def getcallNumber(self):
        if self.is_empty() and self.callnumber == 0:
            self.callnumber = 1
        else:
            self.callnumber += 1
        return self.callnumber

    def getLength(self):
        return self.length


# 服务窗口
class ServiceWindow(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
        self.bankQueue = None
        self.lock = threading.Lock()

    def service(self):
        while True:
            self.lock.acquire()
            time.sleep(10)
            try:
                if not self.bankQueue.is_empty():
                    print("请 %d 号到 %s 号窗口" % (self.bankQueue.front.data, threading.current_thread().name))
                    self.bankQueue.deQueue()
                else:
                    print("队列为空哦!!!")
            finally:
                self.lock.release()

# 客户端
if __name__ == "__main__":
    bankQueue = LinkBankQueue()
    windowcount = 2
    serviceWindows = [None] * windowcount
    threadList = [None] * windowcount
    for i in range(windowcount):
        serviceWindows[i] = ServiceWindow()
        serviceWindows[i].bankQueue = bankQueue
        threadList[i] = threading.Thread(name=(i+1), target=serviceWindows[i].service, args=())
        threadList[i].start()
    while True:
        input("请点击触摸屏获取号码!!!\n")
        callnumber = bankQueue.getcallNumber()
        if bankQueue != None:
            print("您的号码是:%d,您前面有 %d 位" % (callnumber, bankQueue.getLength()))
            bankQueue.enQueue(callnumber)
        else:
            print("您的号码是:%d,您前面有0位" % (callnumber))
5. 字符串

5.1 字符串的定义

  • 串(string)是由零个或多个字符组成的有限序列,又名字符串,记为`S=”a0a1…an”

5.2 字符串的实践
求输入字符串中连续不重复的字符串的最长长度。

  • 分析:这道题主要用到思路是:滑动窗口
    什么是滑动窗口?
    其实就是一个队列,比如例题中的 abcabcbb,进入这个队列(窗口)为 abc 满足题目要求,当再进入 a,队列变成了 abca,这时候不满足要求。所以,我们要移动这个队列!
    如何移动?
    我们只要把队列的左边的元素移出就行了,直到满足题目要求! 一直维持这样的队列,找出队列出现最长的长度时候,求出解!
class Solution():
    def lenOfLongestSubstr(self, s):
        """
        输入:abcabcbb
        :param s:
        :return:
        """
        if not s:
            return 0
        left = 0      # 窗口的左边
        L = len(s)    # 字符串总长度
        lookup = set()
        cur_len = 0
        max_len = 0
        # 窗口右移
        for i in range(L):
            cur_len += 1
            while s[i] in lookup:
                lookup.remove(s[left])
                left += 1
                cur_len -= 1
            if cur_len > max_len:
                max_len = cur_len
            lookup.add(s[i])
        return max_len

参考链接:https://github.com/datawhalechina/team-learning

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值