随笔分类 - 算法
1
摘要:# Varint编码 ## 规则 1. 用7个比特位存储整数的值的部分,最高位(第8位)标识是否还有后续字节。 `0`表示是最后一个字节 `1`表示后面还有 2. 后续字节的每个字节的最高位都是1,其余7位存储整数的值的部分。 ## 案例 以32为int为例 1. 值:1 常规编码:`0000 00
阅读全文
摘要:### 分析 比如 ``` x = 1 res=2 x = 6 res=8 x = 31 res=32 x = 100 res=128 ``` 以100为例,它的二进制表示是 ``` 0110 0100 ``` 128的二进制是 ``` 1000 0000 ``` 不难看出以下结论 1. 2的幂次方
阅读全文
摘要:1. 原理 布隆过滤器拥有K个哈希函数,当一个元素要加入布隆过滤器时,会使用K个哈希函数对其进行计算,得到K个哈希值,然后根据哈希值,在一维数组中把其对应下标的值置位1。 要判断某个数是否在布隆过滤器中,就进行K次哈希计算,得到哈希值,然后在位数组中判断哈希值对应位置是否都为1,如果都为1,就说明这
阅读全文
摘要:数的范围 给定一个升序数组和一个值, 找出这个值在数组中出现的起始和终止位置,如果不存在,返回-1 -1 分析 假定数组长度是n, 整数是target 首先找出起始位置,即找出满足条件的左边界,以以下数组为例 1 2 3 3 3 3 4 target = 3 左边界右边的数据显然满足>= targe
阅读全文
摘要:归并排序-逆序对的数量 原理 略 代码 #include<iostream> using namespace std; const int N = 1e5 + 10; typedef unsigned long long ULL; int s[N], tmp[N]; ULL mergeSort(in
阅读全文
摘要:快速排序总结 原理 二分 + 分治 目标: 选取基准值pivot 根据基准值将数组一分为二,左边<= pivot, 右边 >= pivot 根据pivot位置,将数组一份为二,递归排序处理 代码 #include<iostream> using namespace std; const int N
阅读全文
摘要:算法 集合:所有S[1~i]和P[1~j]的匹配方案 属性:是否存在一个合法方案(bool) 如果p[j] != '*',dp[i][j] = dp[i-1][j-1] && (s[i]==p[j] || p[j]=='?') 如果p[j] == '*',dp[i][j] = dp[i][j - 1
阅读全文
摘要:算法1.三次线性扫描$O(n)$ 观察整个图形,考虑对水的面积按 列 进行拆解 注意到,每个矩形条上方所能接受的水的高度,是由它左边 最高的 矩形,和右边最高的矩形决定的。 具体地,假设第 i 个矩形条的高度为 height[i],且矩形条左边 最高的 矩形条的高度为 left_max[i],右边
阅读全文
摘要:前置算法: 复原数组 先看一个基础算法, 快速复原一个无序数组, 使得nums[i] == i, 且数组中的元素都是从0开始的有序数 比如数组长度为5,那么数组中的元素就是0 1 2 3 4,且不重复 要恢复这个数组,使得num[i] == i, 就是使用交换,代码如下 void reset(vec
阅读全文
摘要:给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列。 思路 首先考虑,在什么情况下出现的重复? 以[1,1,2]为例,分别选了第1个1和第二个1为开头时,会出现重复结果 解决方法是: 如果不选某个元素,那么和这个元素相等的后续元素也应该跳过 即,如果选了第一个1,那么后续的
阅读全文
摘要:思路 为什么会出现重复? 以{1,1,7}和target = 8为例, 如果不选0号位置的1,那么1号位置的1就也不应该选 否则0号位置的1和7构成一个结果 在不选0号位置时,1号位置的1和7又构成一个结果 从而发生重复 所以去重的思路就是如果不选某个元素,那么之后和他相等的元素都应该跳过 代码 c
阅读全文
摘要:思路 先把数组排序 先枚举i,再枚举j,确定了i和j的值,在保证$nums[i] + nums[j] + nums[k - 1] >= 0$的条件下,找到k的最小值,之后查看三数相加是否等于0,如果相等,记录答案,如果不等,那就继续枚举i和j 这里的j和k的确定使用的是双指针做法,因为有序,因此每次
阅读全文
摘要:思路 动态规划 将字符或'.' + '*'当做一个整体进行处理,因此如果下一个位置是*,那就跳过当前位置 当p[j] != '*'时,那就是字符匹配,此时i必须大于0,因为s[i]必须是一个字符才能进行匹配 此时dp[i][j] = dp[i - 1][j - 1] && (s[i] == p[j]
阅读全文
摘要:思路 - 找规律 找规律题 每一行都是等差数列 样例 输入:s = "PAYPALISHIRING", numRows = 3 输出:"PAHNAPLSIIGYIR" 解释: P A H N A P L S I I G Y I R 第一行和最后一行字符间的距离是2*numRows - 2 中间几行:
阅读全文
摘要:思路 原问题难以直接递归求解,所以我们先考虑这样一个问题: 在两个有序数组中,长度分别为n、m, 找出第k小数。 如果该问题可以解决,那么第 k = (n+m)/2 小数就是我们要求的中位数. 先从简单情况入手,假设 m,n ≥ k/2,我们先从 nums1 和 nums2 中各取前 k/2 个元素
阅读全文
摘要:题目地址: https://leetcode.cn/problems/longest-palindromic-substring/ 解法1 - 中心枚举法 思路 有两种回文串 长度为偶数:若中心点坐标为i,左右两坐标起点是i - 1, j + 1 长度为奇数:若中心点坐标为i,左右两坐标起点是i,
阅读全文
摘要:2.二的幂数组中查询范围内的乘积 解法1. 暴力枚举 n最大是1e9,未超出int表示范围,最多有30个2的幂 查询数组最大是1e5 暴力枚举的最差时间复杂度就是$3e6$,不会超时 时间复杂度 求2的幂,$O(\log_2^n)$ m次查询,每次查询最多花费$O(\log_2^n)$,总的时间复杂
阅读全文
摘要:这次差两分钟做出最后一道题 第308场周赛 2389. 和有限的最长子序列 我用的双重循环,时间复杂度挺高的,但是蛮有意思的哈哈哈 class Solution { public: vector<int> answerQueries(vector<int>& nums, vector<int>& q
阅读全文
摘要:这次只做出了三道题 6184. 统计共同度过的日子数 不熟悉api,没用过sscanf,在处理日期字符串的时候耽误了很多时间,最后用的substr()和stoi(stoi还是现场在网上搜的) 没有及时把重复代码提取出去,多写了很多行 class Solution { public: int mont
阅读全文
摘要:二分 二分的关键并不是单调性,而是存在某个性质能使队列一分为二 模板 bool check(int x) {/* ... */} // 检查x是否满足某种性质 // 找左边界或左边界值 int bsearch_1(int l, int r) { while (l < r) { int mid = l
阅读全文
1