LeoJhonSong / Algorithm-Learning

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 编程机考笔记"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 常用代码段\n",
    "\n",
    "- [python算法常用内置库](https://segmentfault.com/a/1190000037505191)\n",
    "\n",
    "### 列表相关"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 列表推导式语法: [output_expression for out_exp in input_list if expression]\n",
    "# 这两种写法一个是两层的遍历, 一个是并行遍历\n",
    "a = [x*y for x in range(1,5) if x > 2 for y in range(1,4) if y < 3]\n",
    "a = [[i, j] for i, j in zip('1234', 'abcd')]\n",
    "\n",
    "# zip拼接\n",
    "l = list(zip(l1, l2, l3))  # 可以拼一组列表\n",
    "\n",
    "# zip纵向解列表\n",
    "l = [[i, j, k] for i, j, k in zip('1234', 'abcd', 'abcd')]\n",
    "a, b, c = zip(*l)\n",
    "# 一维的话也可以直接解 (这样解出来可变长参数始终会是列表, 不管有没有内容)\n",
    "l = [1, 2, 3, 4, 5]\n",
    "start, *middle, end = l\n",
    "\n",
    "# 并行遍历一组可迭代对象\n",
    "letters = ['a', 'b', 'c']\n",
    "numbers = [0, 1, 2]\n",
    "operators = ['*', '/', '+']\n",
    "for l, n, o in zip(letters, numbers, operators):\n",
    "    print(f'{l}{n}{o}')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 字符串相关\n",
    "\n",
    "[fstring官方文档](https://docs.python.org/zh-cn/3/tutorial/inputoutput.html#formatted-string-literals)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 删除字符串中所有指定字符\n",
    "s = s.replace('a', '')\n",
    "# 获得词频\n",
    "from collections import Counter\n",
    "c = Counter(s)  # 可以类似字典地访问"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 字典相关"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# zip拼接\n",
    "d = dict(zip(keys_l, values_l))  # 可以拼出字典\n",
    "\n",
    "# 带默认值的字典\n",
    "import collections\n",
    "list_dict = collections.defaultdict(list)  # list类型的默认值为[]\n",
    "int_dict = collections.defaultdict(int)  # int类型的默认值为0"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 输入输出\n",
    "\n",
    "### stdin/stdout\n",
    "\n",
    "❗进来都是`str`\n",
    "\n",
    "#### 针对单组输入\n",
    "\n",
    "❗`sys.stdin`不会去掉输出末尾的`\\n`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import sys\n",
    "data = [s.strip() for s in sys.stdin.readlines()]\n",
    "\n",
    "for d in data:\n",
    "    pass"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 针对多组输入\n",
    "\n",
    "❗`input()`自带去掉末尾`\\n`功能"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "while True:\n",
    "    try:\n",
    "        s = input()\n",
    "    except:\n",
    "        break"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 易错点\n",
    "\n",
    "1. 给函数传参列表时可以进来先深拷贝一下:`l  = l[:]`\n",
    "2. 删除列表元素时可能越界, 要么在遍历外一次`l.pop()`删完, 要么用列表推导式\n",
    "2. 为了应对可能为空列表的输入, 输出列表最好只赋`[]`初值, 在遍历时不截取而是用整个输入, 这样空列表的话会直接跳出遍历."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 算法\n",
    "\n",
    "### 排序\n",
    "\n",
    "- `sorted(iterable, /, *, key=None, reverse=False)`**iterable**处放个可迭代对象, **key**处放自定义函数来选取比较的参数, 可以是个参数元组\n",
    "- `sorted()`和`list.sort()`对多维列表默认使用第一维排序, 用`key=lambda i: i[idx]`指定维度\n",
    "- `zip()`可用来并行排序, `l = sorted(zip(l1, l2))`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# list\n",
    "l.sort()\n",
    "l = sorted(l)\n",
    "# dict\n",
    "# 按键排序\n",
    "d = sorted(d.items(), key=lambda i: i[0])\n",
    "# 按值排序\n",
    "d = sorted(d.items(), key=lambda i: i[1])\n",
    "# 字典列表\n",
    "d_l = [\n",
    "    { \"name\" : \"Taobao\", \"age\" : 100},\n",
    "    { \"name\" : \"Runoob\", \"age\" : 7 },\n",
    "    { \"name\" : \"Google\", \"age\" : 100 },\n",
    "    { \"name\" : \"Wiki\" , \"age\" : 200 }\n",
    "]\n",
    "# 按age排序\n",
    "d_l = sorted(d_l, key = lambda i: i['age'])\n",
    "# 按age, name排序\n",
    "d_l = sorted(d_l, key = lambda i: (i['age'], i['name']))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 排列组合"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import itertools  # TODO: 这个库要进一步研究\n",
    "arr = [1, 2, 3]\n",
    "list(itertools.permutations(arr, 3))  # 排列Pn3\n",
    "list(itertools.combinations(arr, 2))  # 组合Cn2\n",
    "list(itertools.product(arr))  # TODO: 考虑先后顺序有放回地抽取"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 手动实现全排列\n",
    "\n",
    "##### 普通递归\n",
    "\n",
    "- 确定第一位, 移动指针, 对n-1位遍历\n",
    "- 确定第二位, 移动指针, 对n-2位遍历\n",
    "- ...\n",
    "- 直到只剩一位, 返回值\n",
    "\n",
    "❗ python递归默认最大深度为**1000**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def permutations(arr: list, position: int, end: int) -> None:\n",
    "    if position == end:  # 基本条件\n",
    "        print(arr)\n",
    "    else:\n",
    "        arr = arr.copy()  # 避免对原列表进行操作\n",
    "        for index in range(position, end):\n",
    "            arr[index], arr[position] = arr[position], arr[index]\n",
    "            permutations(arr, position + 1, end)\n",
    "\n",
    "arr = [1, 2, 3]\n",
    "permutations(arr, 0, len(arr))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 回溯法\n",
    "\n",
    "深搜, 返回时回溯\n",
    "\n",
    "[leetcode详细题解](https://leetcode-cn.com/problems/permutations/solution/quan-pai-lie-by-leetcode-solution-2/)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 2, 1], [3, 1, 2]]\n"
     ]
    }
   ],
   "source": [
    "def permute(nums):\n",
    "    \"\"\"\n",
    "    :type nums: List[int]\n",
    "    :rtype: List[List[int]]\n",
    "    \"\"\"\n",
    "    def backtrack(first=0):\n",
    "        # 所有数都填完了\n",
    "        if first == n:\n",
    "            res.append(nums[:])\n",
    "        for i in range(first, n):\n",
    "            # 动态维护数组\n",
    "            nums[first], nums[i] = nums[i], nums[first]\n",
    "            # 继续递归填下一个数\n",
    "            backtrack(first + 1)\n",
    "            # 撤销操作\n",
    "            nums[first], nums[i] = nums[i], nums[first]\n",
    "\n",
    "    n = len(nums)\n",
    "    res = []\n",
    "    backtrack()\n",
    "    return res\n",
    "\n",
    "arr = [1, 2, 3]\n",
    "print(permute(arr))\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 二分查找"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3\n",
      "[1, 6, 3, 3.5, 4, 5]\n"
     ]
    }
   ],
   "source": [
    "import bisect\n",
    "\n",
    "l = [1, 6, 3, 4, 5]\n",
    "item = 3.5\n",
    "print(bisect.bisect_left(l, item))  # TODO: 差值最小?\n",
    "print(bisect.bisect_right(l, item))  # TODO: 差值最小?\n",
    "l.insert(bisect.bisect(l, item), item)\n",
    "print(l)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 深度优先搜索 (DFS)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 广度优先搜索 (BFS)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 滑动窗口\n",
    "\n",
    "#### 无重复最长子字符串"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "max_len = 0\n",
    "start, end = 0, 0"
   ]
  }
 ],
 "metadata": {
  "interpreter": {
   "hash": "767d51c1340bd893661ea55ea3124f6de3c7a262a8b4abca0554b478b1e2ff90"
  },
  "kernelspec": {
   "display_name": "Python 3.10.2 64-bit",
   "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.10.2"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}

About


Languages

Language:Python 65.4%Language:Jupyter Notebook 34.6%