更新练习题
This commit is contained in:
parent
2d41f2adef
commit
397cdacc21
|
@ -0,0 +1,838 @@
|
|||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Task01:数组(1天)\n",
|
||||
"理论部分\n",
|
||||
"\n",
|
||||
"- 理解数组的存储与分类。\n",
|
||||
"- 实现动态数组,该数组能够根据需要修改数组的长度。\n",
|
||||
"\n",
|
||||
"**1. 利用动态数组解决数据存放问题**\n",
|
||||
"\n",
|
||||
"编写一段代码,要求输入一个整数N,用动态数组A来存放2~N之间所有5或7的倍数,输出该数组。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"5,7,10,14,15,20,21,25,28,30,35,40,42,45,49,50,55,56,60,63,65,70,75,77,80,84,85,90,91,95,98,100,"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"def dynamiclist(N):\n",
|
||||
" if N < 2:\n",
|
||||
" return []\n",
|
||||
" return filter(lambda x:x % 5 == 0 or x % 7 == 0, range(2,N+1))\n",
|
||||
"\n",
|
||||
"nums = dynamiclist(100)\n",
|
||||
"for i in nums:\n",
|
||||
" print(i, end = ',')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**2. 托普利茨矩阵问题**\n",
|
||||
"\n",
|
||||
"https://leetcode-cn.com/problems/toeplitz-matrix/\n",
|
||||
"\n",
|
||||
"如果一个矩阵的每一方向由左上到右下的对角线上具有相同元素,那么这个矩阵是托普利茨矩阵。\n",
|
||||
"\n",
|
||||
"给定一个M x N的矩阵,当且仅当它是托普利茨矩阵时返回True。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"```\n",
|
||||
"输入:\n",
|
||||
"matrix = [\n",
|
||||
" [1,2,3,4],\n",
|
||||
" [5,1,2,3],\n",
|
||||
" [9,5,1,2]\n",
|
||||
"]\n",
|
||||
"输出: True\n",
|
||||
"解释:\n",
|
||||
"在上述矩阵中, 其对角线为:\n",
|
||||
"\"[9]\", \"[5, 5]\", \"[1, 1, 1]\", \"[2, 2, 2]\", \"[3, 3]\", \"[4]\"。\n",
|
||||
"各条对角线上的所有元素均相同, 因此答案是`True`。\n",
|
||||
"```"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"说明:\n",
|
||||
"- matrix 是一个包含整数的二维数组。\n",
|
||||
"- matrix 的行数和列数均在 [1, 20]范围内。\n",
|
||||
"- matrix[i][j] 包含的整数在 [0, 99]范围内。\n",
|
||||
"\n",
|
||||
"进阶:\n",
|
||||
"- 如果矩阵存储在磁盘上,并且磁盘内存是有限的,因此一次最多只能将一行矩阵加载到内存中,该怎么办?\n",
|
||||
"- 如果矩阵太大以至于只能一次将部分行加载到内存中,该怎么办?"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"True"
|
||||
]
|
||||
},
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"def toeplitz_mat(matrix):\n",
|
||||
" if not matrix or not matrix[0]:\n",
|
||||
" return False\n",
|
||||
" for i in range(1, len(matrix)):\n",
|
||||
" for j in range(1, len(matrix[0])):\n",
|
||||
" if matrix[i][j] != matrix[i - 1][j - 1]:\n",
|
||||
" return False\n",
|
||||
" return True\n",
|
||||
"\n",
|
||||
"matrix = [[1,2,3,4],\n",
|
||||
" [5,1,2,3],\n",
|
||||
" [9,5,1,2]]\n",
|
||||
"toeplitz_mat(matrix)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"False"
|
||||
]
|
||||
},
|
||||
"execution_count": 7,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"matrix = [[1,2],\n",
|
||||
" [2,2]]\n",
|
||||
"toeplitz_mat(matrix)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**3.三数之和**\n",
|
||||
"\n",
|
||||
"https://leetcode-cn.com/problems/3sum/\n",
|
||||
"\n",
|
||||
"给定一个包含 n 个整数的数组nums,判断nums中是否存在三个元素a,b,c,使得a + b + c = 0?找出所有满足条件且不重复的三元组。\n",
|
||||
"\n",
|
||||
"注意:答案中不可以包含重复的三元组。\n",
|
||||
"\n",
|
||||
"示例:\n",
|
||||
"\n",
|
||||
"```\n",
|
||||
"给定数组 nums = [-1, 0, 1, 2, -1, -4],\n",
|
||||
"\n",
|
||||
"满足要求的三元组集合为:\n",
|
||||
"[\n",
|
||||
" [-1, 0, 1],\n",
|
||||
" [-1, -1, 2]\n",
|
||||
"]\n",
|
||||
"```"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 18,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"[[-1, -1, 2], [-1, 0, 1]]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"def threesum(nums, target = 0):\n",
|
||||
" if len(nums) < 3:\n",
|
||||
" return []\n",
|
||||
" nums.sort()\n",
|
||||
" res = []\n",
|
||||
" for i in range(len(nums) - 2):\n",
|
||||
" if nums[i] > target:\n",
|
||||
" return res\n",
|
||||
" if i > 0 and nums[i] == nums[i - 1]:\n",
|
||||
" continue\n",
|
||||
" l, r = i + 1, len(nums) - 1\n",
|
||||
" while l < r:\n",
|
||||
" sum_ = nums[i] + nums[l] + nums[r]\n",
|
||||
" if sum_ < target:\n",
|
||||
" l += 1\n",
|
||||
" elif sum_ > target:\n",
|
||||
" r -= 1\n",
|
||||
" else:\n",
|
||||
" res.append([nums[i], nums[l], nums[r]])\n",
|
||||
" while l < r and nums[l] == nums[l+1]:\n",
|
||||
" l += 1\n",
|
||||
" while l < r and nums[r] == nums[r-1]:\n",
|
||||
" r -= 1\n",
|
||||
" l += 1\n",
|
||||
" r -= 1\n",
|
||||
" return res\n",
|
||||
" \n",
|
||||
"nums = [-1, 0, 1, 2, -1, -4]\n",
|
||||
"print(threesum(nums))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Task02:顺序表和链表\n",
|
||||
"理论部分\n",
|
||||
"\n",
|
||||
"- 理解线性表的定义与操作。\n",
|
||||
"- 实现顺序表。\n",
|
||||
"- 实现单链表、循环链表、双向链表。\n",
|
||||
"\n",
|
||||
"**1.合并两个有序链表**\n",
|
||||
"\n",
|
||||
"https://leetcode-cn.com/problems/merge-two-sorted-lists/\n",
|
||||
"\n",
|
||||
"将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。\n",
|
||||
"\n",
|
||||
"示例:\n",
|
||||
"\n",
|
||||
"```\n",
|
||||
"输入:1->2->4, 1->3->4\n",
|
||||
"输出:1->1->2->3->4->4\n",
|
||||
"```"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 63,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"1->1->2->3->4->4"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# 链表定义\n",
|
||||
"class ListNode:\n",
|
||||
" def __init__(self, val, nextnode = None):\n",
|
||||
" self.val = val\n",
|
||||
" self.next = nextnode\n",
|
||||
" \n",
|
||||
"# 生成链表\n",
|
||||
"def generate(nums):\n",
|
||||
" head = cur = ListNode(-1)\n",
|
||||
" for i in nums:\n",
|
||||
" cur.next = cur = ListNode(i)\n",
|
||||
" return head.next\n",
|
||||
"\n",
|
||||
"# 递归\n",
|
||||
"def mergelist(head_1, head_2):\n",
|
||||
" if not head_1:\n",
|
||||
" return head_2\n",
|
||||
" elif not head_2:\n",
|
||||
" return head_1\n",
|
||||
" elif head_1.val < head_2.val:\n",
|
||||
" head_1.next = mergelist(head_1.next, head_2)\n",
|
||||
" return head_1\n",
|
||||
" else:\n",
|
||||
" head_2.next = mergelist(head_1, head_2.next)\n",
|
||||
" return head_2\n",
|
||||
" \n",
|
||||
"nums1, nums2 = [1,2,4], [1,3,4]\n",
|
||||
"nums1, nums2 = generate(nums1), generate(nums2)\n",
|
||||
"head = mergelist(nums1, nums2)\n",
|
||||
"while head:\n",
|
||||
" print(head.val, end = '->' if head.next else '')\n",
|
||||
" head = head.next"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 34,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"1->1->2->3->4->4"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# 哑结点\n",
|
||||
"def mergelist_1(head_1, head_2):\n",
|
||||
" head = cur = ListNode(-1)\n",
|
||||
" while head_1 and head_2:\n",
|
||||
" if head_1.val < head_2.val:\n",
|
||||
" cur.next, head_1 = head_1, head_1.next\n",
|
||||
" else:\n",
|
||||
" cur.next, head_2 = head_2, head_2.next\n",
|
||||
" cur = cur.next\n",
|
||||
" cur.next = head_1 if head_1 else head_2\n",
|
||||
" return head.next\n",
|
||||
"\n",
|
||||
"nums1, nums2 = [1,2,4], [1,3,4]\n",
|
||||
"nums1, nums2 = generate(nums1), generate(nums2)\n",
|
||||
"head = mergelist_1(nums1, nums2)\n",
|
||||
"while head:\n",
|
||||
" print(head.val, end = '->' if head.next else '')\n",
|
||||
" head = head.next"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**2. 删除链表的倒数第N个节点**\n",
|
||||
"\n",
|
||||
"https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list/\n",
|
||||
"\n",
|
||||
"给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。\n",
|
||||
"\n",
|
||||
"示例:\n",
|
||||
"```\n",
|
||||
"给定一个链表: 1->2->3->4->5, 和 n = 2.\n",
|
||||
"\n",
|
||||
"当删除了倒数第二个节点后,链表变为 1->2->3->5.\n",
|
||||
"说明:给定的 n 保证是有效的。\n",
|
||||
"\n",
|
||||
"进阶:你能尝试使用一趟扫描实现吗?\n",
|
||||
"```"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 64,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"1->2->3->4"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# 2次扫描\n",
|
||||
"def deletenode(head, n):\n",
|
||||
" cur, ans = head, 0\n",
|
||||
" while cur:\n",
|
||||
" ans += 1\n",
|
||||
" cur = cur.next\n",
|
||||
" dummy = cur = ListNode(-1, head)\n",
|
||||
" for i in range(ans - n):\n",
|
||||
" cur = cur.next\n",
|
||||
" cur.next = cur.next.next\n",
|
||||
" return dummy.next\n",
|
||||
"\n",
|
||||
"nums = generate(range(1, 6))\n",
|
||||
"head = deletenode(nums, 1)\n",
|
||||
"while head:\n",
|
||||
" print(head.val, end = '->' if head.next else '')\n",
|
||||
" head = head.next"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 71,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"1->2->4->5"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# 1次扫描 空间换时间\n",
|
||||
"def deletenode_1(head, n):\n",
|
||||
" hash_map = {}\n",
|
||||
" cur = dummy = ListNode(-1, head)\n",
|
||||
" ans = 0\n",
|
||||
" while cur:\n",
|
||||
" ans += 1\n",
|
||||
" hash_map[ans] = cur\n",
|
||||
" cur = cur.next\n",
|
||||
" # 被删除的节点索引\n",
|
||||
" index = ans - n\n",
|
||||
" hash_map[index].next = hash_map[index].next.next\n",
|
||||
" return dummy.next\n",
|
||||
"\n",
|
||||
"nums = generate(range(1,6))\n",
|
||||
"head = deletenode_1(nums, 3)\n",
|
||||
"while head:\n",
|
||||
" print(head.val, end = '->' if head.next else '')\n",
|
||||
" head = head.next"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 66,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"1->2->3->5"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# 栈实现\n",
|
||||
"def deletenode_2(head, n):\n",
|
||||
" dummy = cur = ListNode(-1, head)\n",
|
||||
" stack = []\n",
|
||||
" while cur:\n",
|
||||
" stack.append(cur)\n",
|
||||
" cur = cur.next\n",
|
||||
" for i in range(n):\n",
|
||||
" stack.pop()\n",
|
||||
" prev = stack[-1]\n",
|
||||
" prev.next = prev.next.next\n",
|
||||
" return dummy.next\n",
|
||||
"\n",
|
||||
"nums = generate(range(1,6))\n",
|
||||
"head = deletenode_2(nums, 2)\n",
|
||||
"while head:\n",
|
||||
" print(head.val, end = '->' if head.next else '')\n",
|
||||
" head = head.next"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**3. 旋转链表**\n",
|
||||
"\n",
|
||||
"https://leetcode-cn.com/problems/rotate-list/\n",
|
||||
"\n",
|
||||
"给定一个链表,旋转链表,将链表每个节点向右移动k个位置,其中k是非负数。\n",
|
||||
"\n",
|
||||
"示例 1:\n",
|
||||
"```\n",
|
||||
"输入: 1->2->3->4->5->NULL, k = 2\n",
|
||||
"输出: 4->5->1->2->3->NULL\n",
|
||||
"\n",
|
||||
"解释:\n",
|
||||
"向右旋转 1 步: 5->1->2->3->4->NULL\n",
|
||||
"向右旋转 2 步: 4->5->1->2->3->NULL\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"示例2:\n",
|
||||
"```\n",
|
||||
"输入: 0->1->2->NULL, k = 4\n",
|
||||
"输出: 2->0->1->NULL\n",
|
||||
"\n",
|
||||
"解释:\n",
|
||||
"向右旋转 1 步: 2->0->1->NULL\n",
|
||||
"向右旋转 2 步: 1->2->0->NULL\n",
|
||||
"向右旋转 3 步: 0->1->2->NULL\n",
|
||||
"向右旋转 4 步: 2->0->1->NULL\n",
|
||||
"```"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 84,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"4->5->1->2->3"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# 首先建立循环链表\n",
|
||||
"def rotate(head, k):\n",
|
||||
" cur, n = head, 1\n",
|
||||
" while cur.next:\n",
|
||||
" cur = cur.next\n",
|
||||
" n += 1\n",
|
||||
" cur.next = head\n",
|
||||
" \n",
|
||||
" new_tail = head\n",
|
||||
" for i in range(n - k%n - 1):\n",
|
||||
" new_tail = new_tail.next\n",
|
||||
" new_head = new_tail.next\n",
|
||||
" new_tail.next = None\n",
|
||||
" return new_head\n",
|
||||
"\n",
|
||||
"nums, k = generate(range(1,6)), 2\n",
|
||||
"head = rotate(nums, k)\n",
|
||||
"while head:\n",
|
||||
" print(head.val, end = '->' if head.next else '')\n",
|
||||
" head = head.next"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Task03:栈与递归\n",
|
||||
"**理论部分**\n",
|
||||
"\n",
|
||||
"- 用数组实现一个顺序栈。\n",
|
||||
"- 用链表实现一个链栈。\n",
|
||||
"- 理解递归的原理。\n",
|
||||
"\n",
|
||||
"**1. 根据要求完成车辆重排的程序代码**\n",
|
||||
"\n",
|
||||
"假设一列货运列车共有n节车厢,每节车厢将停放在不同的车站。假定n个车站的编号分别为1至n,货运列车按照第n站至第1站的次序经过这些车站。车厢的编号与它们的目的地相同。为了便于从列车上卸掉相应的车厢,必须重新排列车厢,使各车厢从前至后按编号1至n的次序排列。当所有的车厢都按照这种次序排列时,在每个车站只需卸掉最后一节车厢即可。\n",
|
||||
"\n",
|
||||
"我们在一个转轨站里完成车厢的重排工作,在转轨站中有一个入轨、一个出轨和k个缓冲铁轨(位于入轨和出轨之间)。图(a)给出一个转轨站,其中有k个(k=3)缓冲铁轨H1,H2 和H3。开始时,n节车厢的货车从入轨处进入转轨站,转轨结束时各车厢从右到左按照编号1至n的次序离开转轨站(通过出轨处)。在图(a)中,n=9,车厢从后至前的初始次序为5,8,1,7,4,2,9,6,3。图(b)给出了按所要求的次序重新排列后的结果。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Task04:队列\n",
|
||||
"**理论部分**\n",
|
||||
"\n",
|
||||
"- 用数组实现一个顺序队列。\n",
|
||||
"- 用数组实现一个循环队列。\n",
|
||||
"- 用链表实现一个链式队列。\n",
|
||||
"\n",
|
||||
"**1. 模拟银行服务完成程序代码。**\n",
|
||||
"\n",
|
||||
"目前,在以银行营业大厅为代表的窗口行业中大量使用排队(叫号)系统,该系统完全模拟了人群排队全过程,通过取票进队、排队等待、叫号服务等功能,代替了人们站队的辛苦。\n",
|
||||
"\n",
|
||||
"排队叫号软件的具体操作流程为:\n",
|
||||
"\n",
|
||||
"- 顾客取服务序号\n",
|
||||
"\n",
|
||||
"当顾客抵达服务大厅时,前往放置在入口处旁的取号机,并按一下其上的相应服务按钮,取号机会自动打印出一张服务单。单上显示服务号及该服务号前面正在等待服务的人数。\n",
|
||||
"\n",
|
||||
"- 服务员工呼叫顾客\n",
|
||||
"\n",
|
||||
"服务员工只需按一下其柜台上呼叫器的相应按钮,则顾客的服务号就会按顺序的显示在显示屏上,并发出“叮咚”和相关语音信息,提示顾客前往该窗口办事。当一位顾客办事完毕后,柜台服务员工只需按呼叫器相应键,即可自动呼叫下一位顾客。\n",
|
||||
"\n",
|
||||
"编写程序模拟上面的工作过程,主要要求如下:\n",
|
||||
"\n",
|
||||
"- 程序运行后,当看到“请点击触摸屏获取号码:”的提示时,只要按回车键,即可显示“您的号码是:XXX,您前面有YYY位”的提示,其中XXX是所获得的服务号码,YYY是在XXX之前来到的正在等待服务的人数。\n",
|
||||
"- 用多线程技术模拟服务窗口(可模拟多个),具有服务员呼叫顾客的行为,假设每个顾客服务的时间是10000ms,时间到后,显示“请XXX号到ZZZ号窗口!”的提示。其中ZZZ是即将为客户服务的窗口号。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"开启服务:S01\n",
|
||||
"\n",
|
||||
"开启服务:S02\n",
|
||||
"\n",
|
||||
"开启服务:S03\n",
|
||||
"Y0001\n",
|
||||
"Y0002\n",
|
||||
"Y0003\n",
|
||||
"Y0004\n",
|
||||
"Y0005\n",
|
||||
"\n",
|
||||
"请Y0001号到S03号窗口!\n",
|
||||
"\n",
|
||||
"请Y0002号到S02号窗口!\n",
|
||||
"\n",
|
||||
"请Y0003号到S01号窗口!\n",
|
||||
"\n",
|
||||
"请Y0004号到S03号窗口!\n",
|
||||
"\n",
|
||||
"请Y0005号到S02号窗口!\n",
|
||||
"\n",
|
||||
"退出服务:S01\n",
|
||||
"\n",
|
||||
"退出服务:S03\n",
|
||||
"\n",
|
||||
"退出服务:S02\n",
|
||||
"\n",
|
||||
"退出服务\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import queue\n",
|
||||
"import threading\n",
|
||||
"import time\n",
|
||||
"\n",
|
||||
"exitFlag = 0\n",
|
||||
"\n",
|
||||
"class BankServe(threading.Thread):\n",
|
||||
" def __init__(self, threadID, name, q):\n",
|
||||
" threading.Thread.__init__(self)\n",
|
||||
" self.threadID = threadID\n",
|
||||
" self.name = name\n",
|
||||
" self.q = q\n",
|
||||
" \n",
|
||||
" def run(self):\n",
|
||||
" print (\"开启服务:\" + self.name + '\\n')\n",
|
||||
" process_data(self.name, self.q)\n",
|
||||
" print (\"退出服务:\" + self.name + '\\n')\n",
|
||||
"\n",
|
||||
"def process_data(threadName, q):\n",
|
||||
" while not exitFlag:\n",
|
||||
" queueLock.acquire()\n",
|
||||
" if not workQueue.empty():\n",
|
||||
" data = q.get()\n",
|
||||
" queueLock.release()\n",
|
||||
" print('请{}号到{}号窗口!\\n'.format(data, threadName))\n",
|
||||
" else:\n",
|
||||
" queueLock.release()\n",
|
||||
" time.sleep(1)\n",
|
||||
"\n",
|
||||
"serve_num = 3\n",
|
||||
"custom_num = 5\n",
|
||||
"queueLock = threading.Lock()\n",
|
||||
"workQueue = queue.Queue(100)\n",
|
||||
"threads = []\n",
|
||||
"threadID = 1\n",
|
||||
"\n",
|
||||
"# 创建新线程\n",
|
||||
"for i in range(serve_num):\n",
|
||||
" thread = BankServe(threadID, 'S' + str(i+1).rjust(2, '0'), workQueue)\n",
|
||||
" thread.start()\n",
|
||||
" threads.append(thread)\n",
|
||||
" threadID += 1\n",
|
||||
"\n",
|
||||
"# 填充队列\n",
|
||||
"queueLock.acquire()\n",
|
||||
"for i in range(custom_num):\n",
|
||||
" print('Y' + str(i+1).rjust(4, '0'))\n",
|
||||
" workQueue.put('Y' + str(i+1).rjust(4, '0'))\n",
|
||||
"queueLock.release()\n",
|
||||
"\n",
|
||||
"# 等待队列清空\n",
|
||||
"while not workQueue.empty():\n",
|
||||
" pass\n",
|
||||
"\n",
|
||||
"# 通知线程是时候退出\n",
|
||||
"exitFlag = 1\n",
|
||||
"\n",
|
||||
"# 等待所有线程完成\n",
|
||||
"for t in threads:\n",
|
||||
" t.join()\n",
|
||||
"print (\"退出服务\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Task05:字符串\n",
|
||||
"**理论部分**\n",
|
||||
"\n",
|
||||
"用数组实现一个顺序的串结构。\n",
|
||||
"为该串结构提供丰富的操作,比如插入子串、在指定位置移除给定长度的子串、在指定位置取子串、连接串、串匹配等。\n",
|
||||
"练习部分\n",
|
||||
"\n",
|
||||
"**1.无重复字符的最长子串**\n",
|
||||
"\n",
|
||||
"https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/\n",
|
||||
"\n",
|
||||
"给定一个字符串,请你找出其中不含有重复字符的最长子串的长度。\n",
|
||||
"\n",
|
||||
"示例1\n",
|
||||
"```\n",
|
||||
"输入: \"abcabcbb\"\n",
|
||||
"输出: 3 \n",
|
||||
"解释: 因为无重复字符的最长子串是 \"abc\",所以其长度为 3。\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"示例2\n",
|
||||
"```\n",
|
||||
"输入: \"bbbbb\"\n",
|
||||
"输出: 1\n",
|
||||
"解释: 因为无重复字符的最长子串是 \"b\",所以其长度为 1。\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"示例3\n",
|
||||
"```\n",
|
||||
"输入: \"pwwkew\"\n",
|
||||
"输出: 3\n",
|
||||
"解释: 因为无重复字符的最长子串是 \"wke\",所以其长度为 3。\n",
|
||||
"请注意,你的答案必须是 子串 的长度,\"pwke\" 是一个子序列,不是子串。\n",
|
||||
"```"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"abcabcbb 3\n",
|
||||
"bbbbb 1\n",
|
||||
"pwwkew 3\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"def lengthoflongestsubstring(s):\n",
|
||||
" if not s:return 0\n",
|
||||
" lookup = set()\n",
|
||||
" maxlen = curlen = left = 0\n",
|
||||
" for i in range(len(s)):\n",
|
||||
" curlen += 1\n",
|
||||
" while s[i] in lookup:\n",
|
||||
" lookup.remove(s[left])\n",
|
||||
" left += 1\n",
|
||||
" curlen -= 1\n",
|
||||
" maxlen = max(maxlen, curlen)\n",
|
||||
" lookup.add(s[i])\n",
|
||||
" return maxlen\n",
|
||||
"\n",
|
||||
"for s in ['abcabcbb','bbbbb','pwwkew']:\n",
|
||||
" print(s, lengthoflongestsubstring(s))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 20,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"[0, 9]"
|
||||
]
|
||||
},
|
||||
"execution_count": 20,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from itertools import permutations\n",
|
||||
"\n",
|
||||
"s = \"barfoothefoobarman\"\n",
|
||||
"words = [\"foo\",\"bar\"]\n",
|
||||
"res = []\n",
|
||||
"for i in map(lambda x:''.join(x), set(permutations(words, len(words)))):\n",
|
||||
" index = s.find(i)\n",
|
||||
" if index != -1:\n",
|
||||
" res.append(index)\n",
|
||||
"res"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 22,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"QWER 0\n",
|
||||
"QQWE 1\n",
|
||||
"QQQW 2\n",
|
||||
"QQQQ 3\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from collections import defaultdict\n",
|
||||
"def balancedString(s):\n",
|
||||
" n = len(s)\n",
|
||||
" if n <=0 or n%4 != 0:\n",
|
||||
" return 0\n",
|
||||
" m = n // 4\n",
|
||||
" dic = defaultdict(int)\n",
|
||||
" for c in s:\n",
|
||||
" dic[c] += 1\n",
|
||||
" if dic['Q']==m and dic['W']==m and dic['E']==m and dic['R']==m: #已经平衡了\n",
|
||||
" return 0\n",
|
||||
" min_window_len = n #窗口内为多了的 窗口外为ok的 没超阈值的\n",
|
||||
" L = 0 #L R 均为实指\n",
|
||||
" for R in range(n):\n",
|
||||
" dic[s[R]] -= 1\n",
|
||||
" while L <= R and dic['Q']<=m and dic['W']<=m and dic['E']<=m and dic['R']<=m:\n",
|
||||
" min_window_len = min(min_window_len, R - L + 1)\n",
|
||||
" dic[s[L]] += 1\n",
|
||||
" L += 1\n",
|
||||
" return min_window_len\n",
|
||||
"\n",
|
||||
"for s in ['QWER','QQWE','QQQW','QQQQ']:\n",
|
||||
" print(s, balancedString(s))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.8.5"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
|
@ -0,0 +1,838 @@
|
|||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Task01:数组(1天)\n",
|
||||
"理论部分\n",
|
||||
"\n",
|
||||
"- 理解数组的存储与分类。\n",
|
||||
"- 实现动态数组,该数组能够根据需要修改数组的长度。\n",
|
||||
"\n",
|
||||
"**1. 利用动态数组解决数据存放问题**\n",
|
||||
"\n",
|
||||
"编写一段代码,要求输入一个整数N,用动态数组A来存放2~N之间所有5或7的倍数,输出该数组。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"5,7,10,14,15,20,21,25,28,30,35,40,42,45,49,50,55,56,60,63,65,70,75,77,80,84,85,90,91,95,98,100,"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"def dynamiclist(N):\n",
|
||||
" if N < 2:\n",
|
||||
" return []\n",
|
||||
" return filter(lambda x:x % 5 == 0 or x % 7 == 0, range(2,N+1))\n",
|
||||
"\n",
|
||||
"nums = dynamiclist(100)\n",
|
||||
"for i in nums:\n",
|
||||
" print(i, end = ',')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**2. 托普利茨矩阵问题**\n",
|
||||
"\n",
|
||||
"https://leetcode-cn.com/problems/toeplitz-matrix/\n",
|
||||
"\n",
|
||||
"如果一个矩阵的每一方向由左上到右下的对角线上具有相同元素,那么这个矩阵是托普利茨矩阵。\n",
|
||||
"\n",
|
||||
"给定一个M x N的矩阵,当且仅当它是托普利茨矩阵时返回True。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"```\n",
|
||||
"输入:\n",
|
||||
"matrix = [\n",
|
||||
" [1,2,3,4],\n",
|
||||
" [5,1,2,3],\n",
|
||||
" [9,5,1,2]\n",
|
||||
"]\n",
|
||||
"输出: True\n",
|
||||
"解释:\n",
|
||||
"在上述矩阵中, 其对角线为:\n",
|
||||
"\"[9]\", \"[5, 5]\", \"[1, 1, 1]\", \"[2, 2, 2]\", \"[3, 3]\", \"[4]\"。\n",
|
||||
"各条对角线上的所有元素均相同, 因此答案是`True`。\n",
|
||||
"```"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"说明:\n",
|
||||
"- matrix 是一个包含整数的二维数组。\n",
|
||||
"- matrix 的行数和列数均在 [1, 20]范围内。\n",
|
||||
"- matrix[i][j] 包含的整数在 [0, 99]范围内。\n",
|
||||
"\n",
|
||||
"进阶:\n",
|
||||
"- 如果矩阵存储在磁盘上,并且磁盘内存是有限的,因此一次最多只能将一行矩阵加载到内存中,该怎么办?\n",
|
||||
"- 如果矩阵太大以至于只能一次将部分行加载到内存中,该怎么办?"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"True"
|
||||
]
|
||||
},
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"def toeplitz_mat(matrix):\n",
|
||||
" if not matrix or not matrix[0]:\n",
|
||||
" return False\n",
|
||||
" for i in range(1, len(matrix)):\n",
|
||||
" for j in range(1, len(matrix[0])):\n",
|
||||
" if matrix[i][j] != matrix[i - 1][j - 1]:\n",
|
||||
" return False\n",
|
||||
" return True\n",
|
||||
"\n",
|
||||
"matrix = [[1,2,3,4],\n",
|
||||
" [5,1,2,3],\n",
|
||||
" [9,5,1,2]]\n",
|
||||
"toeplitz_mat(matrix)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"False"
|
||||
]
|
||||
},
|
||||
"execution_count": 7,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"matrix = [[1,2],\n",
|
||||
" [2,2]]\n",
|
||||
"toeplitz_mat(matrix)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**3.三数之和**\n",
|
||||
"\n",
|
||||
"https://leetcode-cn.com/problems/3sum/\n",
|
||||
"\n",
|
||||
"给定一个包含 n 个整数的数组nums,判断nums中是否存在三个元素a,b,c,使得a + b + c = 0?找出所有满足条件且不重复的三元组。\n",
|
||||
"\n",
|
||||
"注意:答案中不可以包含重复的三元组。\n",
|
||||
"\n",
|
||||
"示例:\n",
|
||||
"\n",
|
||||
"```\n",
|
||||
"给定数组 nums = [-1, 0, 1, 2, -1, -4],\n",
|
||||
"\n",
|
||||
"满足要求的三元组集合为:\n",
|
||||
"[\n",
|
||||
" [-1, 0, 1],\n",
|
||||
" [-1, -1, 2]\n",
|
||||
"]\n",
|
||||
"```"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 18,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"[[-1, -1, 2], [-1, 0, 1]]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"def threesum(nums, target = 0):\n",
|
||||
" if len(nums) < 3:\n",
|
||||
" return []\n",
|
||||
" nums.sort()\n",
|
||||
" res = []\n",
|
||||
" for i in range(len(nums) - 2):\n",
|
||||
" if nums[i] > target:\n",
|
||||
" return res\n",
|
||||
" if i > 0 and nums[i] == nums[i - 1]:\n",
|
||||
" continue\n",
|
||||
" l, r = i + 1, len(nums) - 1\n",
|
||||
" while l < r:\n",
|
||||
" sum_ = nums[i] + nums[l] + nums[r]\n",
|
||||
" if sum_ < target:\n",
|
||||
" l += 1\n",
|
||||
" elif sum_ > target:\n",
|
||||
" r -= 1\n",
|
||||
" else:\n",
|
||||
" res.append([nums[i], nums[l], nums[r]])\n",
|
||||
" while l < r and nums[l] == nums[l+1]:\n",
|
||||
" l += 1\n",
|
||||
" while l < r and nums[r] == nums[r-1]:\n",
|
||||
" r -= 1\n",
|
||||
" l += 1\n",
|
||||
" r -= 1\n",
|
||||
" return res\n",
|
||||
" \n",
|
||||
"nums = [-1, 0, 1, 2, -1, -4]\n",
|
||||
"print(threesum(nums))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Task02:顺序表和链表\n",
|
||||
"理论部分\n",
|
||||
"\n",
|
||||
"- 理解线性表的定义与操作。\n",
|
||||
"- 实现顺序表。\n",
|
||||
"- 实现单链表、循环链表、双向链表。\n",
|
||||
"\n",
|
||||
"**1.合并两个有序链表**\n",
|
||||
"\n",
|
||||
"https://leetcode-cn.com/problems/merge-two-sorted-lists/\n",
|
||||
"\n",
|
||||
"将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。\n",
|
||||
"\n",
|
||||
"示例:\n",
|
||||
"\n",
|
||||
"```\n",
|
||||
"输入:1->2->4, 1->3->4\n",
|
||||
"输出:1->1->2->3->4->4\n",
|
||||
"```"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 63,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"1->1->2->3->4->4"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# 链表定义\n",
|
||||
"class ListNode:\n",
|
||||
" def __init__(self, val, nextnode = None):\n",
|
||||
" self.val = val\n",
|
||||
" self.next = nextnode\n",
|
||||
" \n",
|
||||
"# 生成链表\n",
|
||||
"def generate(nums):\n",
|
||||
" head = cur = ListNode(-1)\n",
|
||||
" for i in nums:\n",
|
||||
" cur.next = cur = ListNode(i)\n",
|
||||
" return head.next\n",
|
||||
"\n",
|
||||
"# 递归\n",
|
||||
"def mergelist(head_1, head_2):\n",
|
||||
" if not head_1:\n",
|
||||
" return head_2\n",
|
||||
" elif not head_2:\n",
|
||||
" return head_1\n",
|
||||
" elif head_1.val < head_2.val:\n",
|
||||
" head_1.next = mergelist(head_1.next, head_2)\n",
|
||||
" return head_1\n",
|
||||
" else:\n",
|
||||
" head_2.next = mergelist(head_1, head_2.next)\n",
|
||||
" return head_2\n",
|
||||
" \n",
|
||||
"nums1, nums2 = [1,2,4], [1,3,4]\n",
|
||||
"nums1, nums2 = generate(nums1), generate(nums2)\n",
|
||||
"head = mergelist(nums1, nums2)\n",
|
||||
"while head:\n",
|
||||
" print(head.val, end = '->' if head.next else '')\n",
|
||||
" head = head.next"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 34,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"1->1->2->3->4->4"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# 哑结点\n",
|
||||
"def mergelist_1(head_1, head_2):\n",
|
||||
" head = cur = ListNode(-1)\n",
|
||||
" while head_1 and head_2:\n",
|
||||
" if head_1.val < head_2.val:\n",
|
||||
" cur.next, head_1 = head_1, head_1.next\n",
|
||||
" else:\n",
|
||||
" cur.next, head_2 = head_2, head_2.next\n",
|
||||
" cur = cur.next\n",
|
||||
" cur.next = head_1 if head_1 else head_2\n",
|
||||
" return head.next\n",
|
||||
"\n",
|
||||
"nums1, nums2 = [1,2,4], [1,3,4]\n",
|
||||
"nums1, nums2 = generate(nums1), generate(nums2)\n",
|
||||
"head = mergelist_1(nums1, nums2)\n",
|
||||
"while head:\n",
|
||||
" print(head.val, end = '->' if head.next else '')\n",
|
||||
" head = head.next"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**2. 删除链表的倒数第N个节点**\n",
|
||||
"\n",
|
||||
"https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list/\n",
|
||||
"\n",
|
||||
"给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。\n",
|
||||
"\n",
|
||||
"示例:\n",
|
||||
"```\n",
|
||||
"给定一个链表: 1->2->3->4->5, 和 n = 2.\n",
|
||||
"\n",
|
||||
"当删除了倒数第二个节点后,链表变为 1->2->3->5.\n",
|
||||
"说明:给定的 n 保证是有效的。\n",
|
||||
"\n",
|
||||
"进阶:你能尝试使用一趟扫描实现吗?\n",
|
||||
"```"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 64,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"1->2->3->4"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# 2次扫描\n",
|
||||
"def deletenode(head, n):\n",
|
||||
" cur, ans = head, 0\n",
|
||||
" while cur:\n",
|
||||
" ans += 1\n",
|
||||
" cur = cur.next\n",
|
||||
" dummy = cur = ListNode(-1, head)\n",
|
||||
" for i in range(ans - n):\n",
|
||||
" cur = cur.next\n",
|
||||
" cur.next = cur.next.next\n",
|
||||
" return dummy.next\n",
|
||||
"\n",
|
||||
"nums = generate(range(1, 6))\n",
|
||||
"head = deletenode(nums, 1)\n",
|
||||
"while head:\n",
|
||||
" print(head.val, end = '->' if head.next else '')\n",
|
||||
" head = head.next"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 71,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"1->2->4->5"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# 1次扫描 空间换时间\n",
|
||||
"def deletenode_1(head, n):\n",
|
||||
" hash_map = {}\n",
|
||||
" cur = dummy = ListNode(-1, head)\n",
|
||||
" ans = 0\n",
|
||||
" while cur:\n",
|
||||
" ans += 1\n",
|
||||
" hash_map[ans] = cur\n",
|
||||
" cur = cur.next\n",
|
||||
" # 被删除的节点索引\n",
|
||||
" index = ans - n\n",
|
||||
" hash_map[index].next = hash_map[index].next.next\n",
|
||||
" return dummy.next\n",
|
||||
"\n",
|
||||
"nums = generate(range(1,6))\n",
|
||||
"head = deletenode_1(nums, 3)\n",
|
||||
"while head:\n",
|
||||
" print(head.val, end = '->' if head.next else '')\n",
|
||||
" head = head.next"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 66,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"1->2->3->5"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# 栈实现\n",
|
||||
"def deletenode_2(head, n):\n",
|
||||
" dummy = cur = ListNode(-1, head)\n",
|
||||
" stack = []\n",
|
||||
" while cur:\n",
|
||||
" stack.append(cur)\n",
|
||||
" cur = cur.next\n",
|
||||
" for i in range(n):\n",
|
||||
" stack.pop()\n",
|
||||
" prev = stack[-1]\n",
|
||||
" prev.next = prev.next.next\n",
|
||||
" return dummy.next\n",
|
||||
"\n",
|
||||
"nums = generate(range(1,6))\n",
|
||||
"head = deletenode_2(nums, 2)\n",
|
||||
"while head:\n",
|
||||
" print(head.val, end = '->' if head.next else '')\n",
|
||||
" head = head.next"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"**3. 旋转链表**\n",
|
||||
"\n",
|
||||
"https://leetcode-cn.com/problems/rotate-list/\n",
|
||||
"\n",
|
||||
"给定一个链表,旋转链表,将链表每个节点向右移动k个位置,其中k是非负数。\n",
|
||||
"\n",
|
||||
"示例 1:\n",
|
||||
"```\n",
|
||||
"输入: 1->2->3->4->5->NULL, k = 2\n",
|
||||
"输出: 4->5->1->2->3->NULL\n",
|
||||
"\n",
|
||||
"解释:\n",
|
||||
"向右旋转 1 步: 5->1->2->3->4->NULL\n",
|
||||
"向右旋转 2 步: 4->5->1->2->3->NULL\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"示例2:\n",
|
||||
"```\n",
|
||||
"输入: 0->1->2->NULL, k = 4\n",
|
||||
"输出: 2->0->1->NULL\n",
|
||||
"\n",
|
||||
"解释:\n",
|
||||
"向右旋转 1 步: 2->0->1->NULL\n",
|
||||
"向右旋转 2 步: 1->2->0->NULL\n",
|
||||
"向右旋转 3 步: 0->1->2->NULL\n",
|
||||
"向右旋转 4 步: 2->0->1->NULL\n",
|
||||
"```"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 84,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"4->5->1->2->3"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# 首先建立循环链表\n",
|
||||
"def rotate(head, k):\n",
|
||||
" cur, n = head, 1\n",
|
||||
" while cur.next:\n",
|
||||
" cur = cur.next\n",
|
||||
" n += 1\n",
|
||||
" cur.next = head\n",
|
||||
" \n",
|
||||
" new_tail = head\n",
|
||||
" for i in range(n - k%n - 1):\n",
|
||||
" new_tail = new_tail.next\n",
|
||||
" new_head = new_tail.next\n",
|
||||
" new_tail.next = None\n",
|
||||
" return new_head\n",
|
||||
"\n",
|
||||
"nums, k = generate(range(1,6)), 2\n",
|
||||
"head = rotate(nums, k)\n",
|
||||
"while head:\n",
|
||||
" print(head.val, end = '->' if head.next else '')\n",
|
||||
" head = head.next"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Task03:栈与递归\n",
|
||||
"**理论部分**\n",
|
||||
"\n",
|
||||
"- 用数组实现一个顺序栈。\n",
|
||||
"- 用链表实现一个链栈。\n",
|
||||
"- 理解递归的原理。\n",
|
||||
"\n",
|
||||
"**1. 根据要求完成车辆重排的程序代码**\n",
|
||||
"\n",
|
||||
"假设一列货运列车共有n节车厢,每节车厢将停放在不同的车站。假定n个车站的编号分别为1至n,货运列车按照第n站至第1站的次序经过这些车站。车厢的编号与它们的目的地相同。为了便于从列车上卸掉相应的车厢,必须重新排列车厢,使各车厢从前至后按编号1至n的次序排列。当所有的车厢都按照这种次序排列时,在每个车站只需卸掉最后一节车厢即可。\n",
|
||||
"\n",
|
||||
"我们在一个转轨站里完成车厢的重排工作,在转轨站中有一个入轨、一个出轨和k个缓冲铁轨(位于入轨和出轨之间)。图(a)给出一个转轨站,其中有k个(k=3)缓冲铁轨H1,H2 和H3。开始时,n节车厢的货车从入轨处进入转轨站,转轨结束时各车厢从右到左按照编号1至n的次序离开转轨站(通过出轨处)。在图(a)中,n=9,车厢从后至前的初始次序为5,8,1,7,4,2,9,6,3。图(b)给出了按所要求的次序重新排列后的结果。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Task04:队列\n",
|
||||
"**理论部分**\n",
|
||||
"\n",
|
||||
"- 用数组实现一个顺序队列。\n",
|
||||
"- 用数组实现一个循环队列。\n",
|
||||
"- 用链表实现一个链式队列。\n",
|
||||
"\n",
|
||||
"**1. 模拟银行服务完成程序代码。**\n",
|
||||
"\n",
|
||||
"目前,在以银行营业大厅为代表的窗口行业中大量使用排队(叫号)系统,该系统完全模拟了人群排队全过程,通过取票进队、排队等待、叫号服务等功能,代替了人们站队的辛苦。\n",
|
||||
"\n",
|
||||
"排队叫号软件的具体操作流程为:\n",
|
||||
"\n",
|
||||
"- 顾客取服务序号\n",
|
||||
"\n",
|
||||
"当顾客抵达服务大厅时,前往放置在入口处旁的取号机,并按一下其上的相应服务按钮,取号机会自动打印出一张服务单。单上显示服务号及该服务号前面正在等待服务的人数。\n",
|
||||
"\n",
|
||||
"- 服务员工呼叫顾客\n",
|
||||
"\n",
|
||||
"服务员工只需按一下其柜台上呼叫器的相应按钮,则顾客的服务号就会按顺序的显示在显示屏上,并发出“叮咚”和相关语音信息,提示顾客前往该窗口办事。当一位顾客办事完毕后,柜台服务员工只需按呼叫器相应键,即可自动呼叫下一位顾客。\n",
|
||||
"\n",
|
||||
"编写程序模拟上面的工作过程,主要要求如下:\n",
|
||||
"\n",
|
||||
"- 程序运行后,当看到“请点击触摸屏获取号码:”的提示时,只要按回车键,即可显示“您的号码是:XXX,您前面有YYY位”的提示,其中XXX是所获得的服务号码,YYY是在XXX之前来到的正在等待服务的人数。\n",
|
||||
"- 用多线程技术模拟服务窗口(可模拟多个),具有服务员呼叫顾客的行为,假设每个顾客服务的时间是10000ms,时间到后,显示“请XXX号到ZZZ号窗口!”的提示。其中ZZZ是即将为客户服务的窗口号。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"开启服务:S01\n",
|
||||
"\n",
|
||||
"开启服务:S02\n",
|
||||
"\n",
|
||||
"开启服务:S03\n",
|
||||
"Y0001\n",
|
||||
"Y0002\n",
|
||||
"Y0003\n",
|
||||
"Y0004\n",
|
||||
"Y0005\n",
|
||||
"\n",
|
||||
"请Y0001号到S03号窗口!\n",
|
||||
"\n",
|
||||
"请Y0002号到S02号窗口!\n",
|
||||
"\n",
|
||||
"请Y0003号到S01号窗口!\n",
|
||||
"\n",
|
||||
"请Y0004号到S03号窗口!\n",
|
||||
"\n",
|
||||
"请Y0005号到S02号窗口!\n",
|
||||
"\n",
|
||||
"退出服务:S01\n",
|
||||
"\n",
|
||||
"退出服务:S03\n",
|
||||
"\n",
|
||||
"退出服务:S02\n",
|
||||
"\n",
|
||||
"退出服务\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import queue\n",
|
||||
"import threading\n",
|
||||
"import time\n",
|
||||
"\n",
|
||||
"exitFlag = 0\n",
|
||||
"\n",
|
||||
"class BankServe(threading.Thread):\n",
|
||||
" def __init__(self, threadID, name, q):\n",
|
||||
" threading.Thread.__init__(self)\n",
|
||||
" self.threadID = threadID\n",
|
||||
" self.name = name\n",
|
||||
" self.q = q\n",
|
||||
" \n",
|
||||
" def run(self):\n",
|
||||
" print (\"开启服务:\" + self.name + '\\n')\n",
|
||||
" process_data(self.name, self.q)\n",
|
||||
" print (\"退出服务:\" + self.name + '\\n')\n",
|
||||
"\n",
|
||||
"def process_data(threadName, q):\n",
|
||||
" while not exitFlag:\n",
|
||||
" queueLock.acquire()\n",
|
||||
" if not workQueue.empty():\n",
|
||||
" data = q.get()\n",
|
||||
" queueLock.release()\n",
|
||||
" print('请{}号到{}号窗口!\\n'.format(data, threadName))\n",
|
||||
" else:\n",
|
||||
" queueLock.release()\n",
|
||||
" time.sleep(1)\n",
|
||||
"\n",
|
||||
"serve_num = 3\n",
|
||||
"custom_num = 5\n",
|
||||
"queueLock = threading.Lock()\n",
|
||||
"workQueue = queue.Queue(100)\n",
|
||||
"threads = []\n",
|
||||
"threadID = 1\n",
|
||||
"\n",
|
||||
"# 创建新线程\n",
|
||||
"for i in range(serve_num):\n",
|
||||
" thread = BankServe(threadID, 'S' + str(i+1).rjust(2, '0'), workQueue)\n",
|
||||
" thread.start()\n",
|
||||
" threads.append(thread)\n",
|
||||
" threadID += 1\n",
|
||||
"\n",
|
||||
"# 填充队列\n",
|
||||
"queueLock.acquire()\n",
|
||||
"for i in range(custom_num):\n",
|
||||
" print('Y' + str(i+1).rjust(4, '0'))\n",
|
||||
" workQueue.put('Y' + str(i+1).rjust(4, '0'))\n",
|
||||
"queueLock.release()\n",
|
||||
"\n",
|
||||
"# 等待队列清空\n",
|
||||
"while not workQueue.empty():\n",
|
||||
" pass\n",
|
||||
"\n",
|
||||
"# 通知线程是时候退出\n",
|
||||
"exitFlag = 1\n",
|
||||
"\n",
|
||||
"# 等待所有线程完成\n",
|
||||
"for t in threads:\n",
|
||||
" t.join()\n",
|
||||
"print (\"退出服务\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Task05:字符串\n",
|
||||
"**理论部分**\n",
|
||||
"\n",
|
||||
"用数组实现一个顺序的串结构。\n",
|
||||
"为该串结构提供丰富的操作,比如插入子串、在指定位置移除给定长度的子串、在指定位置取子串、连接串、串匹配等。\n",
|
||||
"练习部分\n",
|
||||
"\n",
|
||||
"**1.无重复字符的最长子串**\n",
|
||||
"\n",
|
||||
"https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/\n",
|
||||
"\n",
|
||||
"给定一个字符串,请你找出其中不含有重复字符的最长子串的长度。\n",
|
||||
"\n",
|
||||
"示例1\n",
|
||||
"```\n",
|
||||
"输入: \"abcabcbb\"\n",
|
||||
"输出: 3 \n",
|
||||
"解释: 因为无重复字符的最长子串是 \"abc\",所以其长度为 3。\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"示例2\n",
|
||||
"```\n",
|
||||
"输入: \"bbbbb\"\n",
|
||||
"输出: 1\n",
|
||||
"解释: 因为无重复字符的最长子串是 \"b\",所以其长度为 1。\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"示例3\n",
|
||||
"```\n",
|
||||
"输入: \"pwwkew\"\n",
|
||||
"输出: 3\n",
|
||||
"解释: 因为无重复字符的最长子串是 \"wke\",所以其长度为 3。\n",
|
||||
"请注意,你的答案必须是 子串 的长度,\"pwke\" 是一个子序列,不是子串。\n",
|
||||
"```"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"abcabcbb 3\n",
|
||||
"bbbbb 1\n",
|
||||
"pwwkew 3\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"def lengthoflongestsubstring(s):\n",
|
||||
" if not s:return 0\n",
|
||||
" lookup = set()\n",
|
||||
" maxlen = curlen = left = 0\n",
|
||||
" for i in range(len(s)):\n",
|
||||
" curlen += 1\n",
|
||||
" while s[i] in lookup:\n",
|
||||
" lookup.remove(s[left])\n",
|
||||
" left += 1\n",
|
||||
" curlen -= 1\n",
|
||||
" maxlen = max(maxlen, curlen)\n",
|
||||
" lookup.add(s[i])\n",
|
||||
" return maxlen\n",
|
||||
"\n",
|
||||
"for s in ['abcabcbb','bbbbb','pwwkew']:\n",
|
||||
" print(s, lengthoflongestsubstring(s))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 20,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"[0, 9]"
|
||||
]
|
||||
},
|
||||
"execution_count": 20,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from itertools import permutations\n",
|
||||
"\n",
|
||||
"s = \"barfoothefoobarman\"\n",
|
||||
"words = [\"foo\",\"bar\"]\n",
|
||||
"res = []\n",
|
||||
"for i in map(lambda x:''.join(x), set(permutations(words, len(words)))):\n",
|
||||
" index = s.find(i)\n",
|
||||
" if index != -1:\n",
|
||||
" res.append(index)\n",
|
||||
"res"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 22,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"QWER 0\n",
|
||||
"QQWE 1\n",
|
||||
"QQQW 2\n",
|
||||
"QQQQ 3\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from collections import defaultdict\n",
|
||||
"def balancedString(s):\n",
|
||||
" n = len(s)\n",
|
||||
" if n <=0 or n%4 != 0:\n",
|
||||
" return 0\n",
|
||||
" m = n // 4\n",
|
||||
" dic = defaultdict(int)\n",
|
||||
" for c in s:\n",
|
||||
" dic[c] += 1\n",
|
||||
" if dic['Q']==m and dic['W']==m and dic['E']==m and dic['R']==m: #已经平衡了\n",
|
||||
" return 0\n",
|
||||
" min_window_len = n #窗口内为多了的 窗口外为ok的 没超阈值的\n",
|
||||
" L = 0 #L R 均为实指\n",
|
||||
" for R in range(n):\n",
|
||||
" dic[s[R]] -= 1\n",
|
||||
" while L <= R and dic['Q']<=m and dic['W']<=m and dic['E']<=m and dic['R']<=m:\n",
|
||||
" min_window_len = min(min_window_len, R - L + 1)\n",
|
||||
" dic[s[L]] += 1\n",
|
||||
" L += 1\n",
|
||||
" return min_window_len\n",
|
||||
"\n",
|
||||
"for s in ['QWER','QQWE','QQQW','QQQQ']:\n",
|
||||
" print(s, balancedString(s))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.8.5"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
Loading…
Reference in New Issue