刷题(一)

没事写两题,练练思维

  • 运算技巧

    N*2+1 --> N<<1|1
    L+(R-L)/2 --> L+((R-L)>>1)
    6^7 异或运算
    

链表

链表反转
  • # 单链表
    class Node:
        def __init__(self, x):
            self.value = x
            self.next = None
    
    # 双链表
    class DoubleNode:
        def __init__(self, x):
            self.value = x
            self.pre = None
            self.next = None
           
    # 单链表反转
    def reverse_link_list(head):
        pre = None
        cur = None
        while head:
            cur = head.next
            head.next = pre
            pre = head
            head = cur
        return pre
    
    # 双链表反转
    def reverse_double_link_list(head):
        pre = None
        cur = None
        while head:
            cur = head.next
            head.next = pre
            head.pre = cur
            pre = head
            head = cur
        return pre
    
    # 对数器
    def test_reverse_link_list(head):
        if head is None:
            return None
        arr = []
        while head:
            arr.append(head)
            head = head.next
        arr[0].next = None
        for i in range(len(arr), 0, -1):
            arr[i].next = arr[i-1]
        return arr[-1]
    
    def test_reverse_double_link_list(head):
        if head is None:
            return None
        arr = []
        while head:
            arr.append(head)
            head = head.next
        arr[0].next = None
        pre = arr[0]
        for i in range(1, len(arr)):
            cur = arr[i]
            cur.pre = None
            cur.next = pre
            pre.pre = cur
            pre = cur
        return arr[-1]
    
    def generate_random_link_list(length, value):
        import random
        size = int(random.random()*(length+1))
        if size == 0:
            return None
        size -= 1
        head = Node(int(random.random()*(value+1)))
        pre = head
        while size:
            cur = Node(int(random.random()*(value+1)))
            pre.next = cur
            pre = cur
            size -= 1
        return head
    
    def generate_random_double_link_list(length, value):
        import random
        size = int(random.random()*(length+1))
        if size == 0:
            return None
        size -= 1
        head = DoubleNode(int(random.random()*(value+1)))
        pre = head
        while size:
            cur = DoubleNode(int(random.random()*(value+1)))
            pre.next = cur
            cur.pre = pre
            pre = cur
            size -= 1
        return head
    
    # 无环检查链表是否反转有误
    def check_link_list(head1, head2):
        while head1 is None and head2 is None:
            if head1.value != head2.value
            return False
        head1 = head1.next
        head2 = head2.next
        return head1 is None and head2 is None
    
    def check_double_link_list(head1, head2):
        n1 = head1==None
        n2 = head2==None
        if n1 and n2:
            return True
        if n1 ^ n2:
            return False
        if head1.pre is not None or head2.pre is not None:
            return False
        
        end1 = None
        end2 = None
        while head is not None and head2 is not None:
            if head1.value != head2.value:
                return False
            end1 = head1
            end2 = head2
            head1 = head1.next
            head2 = head2.next
        if head1 is not None or head2 is not None:
            return False
        while end1 is not None and end2 is not None:
            if end1.value != end2.value:
                return False
            end1 = end1.pre
            end2 = end2.pre
        return end1 is None and end2 is None
    
    def main():
        length = 20
        value = 100
        times = 10000
        for i in range(times):
            node1 = generate_random_link_list(length, value)
            rev1 = reverse_link_list(node1)
            rev2 = test_reverse_link_list(node1)
            if not check_link_list(rev1, rev2):
                print("false")
                break
    
删除指定结点
  • class Node:
        def __init(self, x):
            self.value = x
            self.next = None
    
    def remove_value(head, num):
        # 删除头结点中包含指定数字的结点
        while head:
            if head != num:
                break
            head = head.next
        pre = head
        cur = head
        
        while cur:
            if cur.value == num:
                pre.next= cur.next
            else:
                pre = cur
          	cur = cur.next
        return head
    
双向列表实现双端队列
  • class Node:
        def __init__(self, x):
            self.value = x
            self.pre = None
            self.next = None
            
    # 双端队列
    class DoubleEndQueue:
        def __init__(self):
            self.head = None
            self.tail = None
            
        def _addtohead(self, value):
            cur = Node(value)
            if head is None:
                head = cur
                tail = cur
            else:
                cur.next = head
                head.pre = cur
                head = cur
        
        def _addtobottom(self, value):
            cur = Node(value)
            if head is None:
                head = cur
                tail = cur
            else:
                cur.pre = tail
                tail.next = cur
                tail = cur
        
        def _popfromhead(self):
            if head is None:
                return None
            cur = head
            if head == tail:
                head = None
                tail = None
            else:
                head = head.next
                cur.next = None
                head.pre = None
            return cur.value
        
        def _popfrombottom(self):
            if head is None:
                return 
            cur = tail
            if head == tail:
                head = None
                tail = None
            else:
                tail = tail.pre
                cur.pre = None
                tail.next = None
            return cur.value
        
        def _isEmpty(self):
            return head == None
        
    # 
    class MyStack:
        def __init__(self):
            self.stack = DoubleEndQueue()
            
        def push(self, value):
            self.stack._addtohead(value)
           
        def pop(self):
            return self.stack._popfromhead()
        
        def isEmpty(self):
            return self.stack._isEmpty()
      
    class MyQueue:
        def __init__(self):
            self.queue = DoubleEndQueue()
           
        def push(self, value):
            self.queue._addtohead(value)
           
        def poll(self):
            return self.queue._popfrombottom()
        
        def isEmpty(self):
            return self.queue._isEmpty()
          
    # python 库中栈
    from collections import deque
    stack = deque
    import queue
    que = queue.Queue(3)	# 先入先出队列
    que = queue.LidoQueue(3)	# 后入先出队列
    que = queue.PriorityQueue(3)	# 优先级队列
    
每日一题
  • class WiggleSubsuquence:
        def __init__(self, nums:list):
            n = len(nums)
            out = nums[1] - nums[0] 
            res = 1 if out == 0 else 2
            for i in range(2, n):
                dif = nums[i] - num[i-1]
                if (dif > 0 and out <=0) or (dif <0 and out >= 0):
                    res += 1
            return res
    
归并排序
  • # 使用递归
    class MergeSort:
        def __init__(self, arr):
            self.arr = arr
        
        def __call__(self):
            if self.arr is None and len(self.arr) < 2:
                retunr self.arr
            self.sort(0, len(arr)-1)
           
        def sort(self, l, r):
            if l == r:
                return 
            mid =  l+ (r - l) >> 1
            sort(l, mid)
            sort(mid+1, r)
            merge(l, mid, r)
           
        def merge(self, l, m, r):
            mid_arr = []
            ptr1 = l
            ptr2 = m + 1
            i = 0
            while prt1 <= m and ptr2 <= r:
                mid_arr[i] = self.arr[p1] if self.arr[p1] <= self.arr[p2] else self.arr[p2] 
                i += 1
                ptr1 += 1
                ptr2 += 1
                
            while ptr1 <= m:
                mid_arr[i] = self.arr[ptr1]
                i += 1
                ptr1 += 1
            
            while ptr2 <= r:
                mid_arr[i] = self.arr[ptr2]
                i += 1
                ptr2 += 1
               
            for j in range(len(mid_arr)):
                self.arr[l+i] = mid_arr[i]
               
         
    # 非递归版本mergeSort
    class MergeSort:
        def __init__(self, arr):
            self.arr = arr
            self.length = len(arr)
        def __call__(self):
            if self.arr is None and self.length < 2:
                return
            mergeSize = 1
            while mergeSize < self.length:
                l = 0
                while l < self.length:
                    if mergeSize >= self.length-l:
                        break
                    m = l + mergeSize - 1
                    r = l + min(m, self.length-p1-1)
                    self.merge(l, m, r)
                    l = r + 1
                    
                # 防止溢出
                if mergeSize > self.length //2 :
                    break
                mergeSize <<= 1
        
        # l -> 最左边, m -> 中间, r -> 最右边 
        def merge(self, l, m, r):
            help_arr = []
            p1 = l
            p2 = m + 1
            i = 0
            while p1 <= m and p2 <= r:
            	if self.arr[p1] <= self.arr[p2]:
                    help_arr[i] = self.arr[p1]
                    p1 += 1
                else:
                    help_arr[i] = self.arr[p2]
                    p2 += 1
                i += 1
               
            while p1 <= m:
                help_arr[i] = self.arr[i]
            while p2 <= r:
                help_arr[i] = self.arr[i]
               
            for j in range(len(help_arr)):
                self.arr[l+j] = help_arr[j]
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值