没事写两题,练练思维
-
运算技巧
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]