自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(25)
  • 收藏
  • 关注

原创 Q30 用插线板制作章鱼脚状线路 dp

对工程师而言,确保电源是最重要的事情。不仅是 PC,当智能手机、平板电脑、数码相机等电量不足时,我们也肯定要四处寻找插座。不过,多人共用的时候就必须共享插座,这时插线板就会派上用场。一般的插线板除了有延长线,还会有多个插口。这里假设有双插口和三插口的插线板。墙壁上只有 1 个插座能用,而需要用电的电器有 n 台,试考虑此时应如何分配插线板。举个例子,当 n= 4 时,如 图 21 所示,有 4 种插线板插线方法(使用同一个插线板时,不考虑插口位置,只考虑插线板的连接方法。另外,要使插线板上最后没有多余的插

2020-12-27 20:38:54 233

原创 Q26 高效的立体停车场 华容道变形

最近,一些公寓等建筑也都配备了立体停车场。立体停车场可以充分利用窄小的土地,通过上下左右移动来停车、出库,从而尽可能多地停车。现在有一个立体停车场,车出库时是把车往没有车的位置移动,从而把某台车移动到出库位置。假设要把左上角的车移动到右下角,试找出路径最短时的操作步数。举个例子,在 3×2 的停车场用如 图 13 所示的方式移动时,需要移动 13 步。不过,如果用如 图 14 所示的移动方法,则只需要移动 9 步。此题一定不是盲目搜索的,因为没有停止条件,我们无法判断一个状态是否为最优。知道这一点

2020-12-27 15:29:40 271

原创 Q18 水果酥饼日 搜索

日本每月的 22 日是水果酥饼日。因为看日历的时候,22 日的上方刚好是 15 日,也就是“‘22’ 这个数字上面点缀着草莓”[1]切分酥饼的时候,要求切分后每一块上面的草莓个数都不相同。假设切分出来的 N 块酥饼上要各有“1~N 个(共 N(N + 1)÷2 个草莓)”。但这里要追加一个条件,那就是“一定要使相邻的两块酥饼上的数字之和是平方数”。举个例子,假设 N = 4 时采用如 图 4 的切法。这时,虽然 1 + 3 = 4 得到的是平方数,但“1 和 4” “2 和 3” “2 和 4”的部分

2020-12-27 15:20:05 88

原创 Q04 切分木棒 优先队列

假设要把长度为 n 厘米的木棒切分为 1 厘米长的小段,但是 1 根木棒只能由 1 人切分,当木棒被切分为 3 段后,可以同时由 3 个人分别切分木棒。思路很简单,优先队列即可,每次把最长的排出来切分,代码如下:...

2020-12-27 15:13:43 77

原创 leetcode 85 暴力+dp+单调栈 无敌题目

解法一:中等暴力提前预存好每个竖的连续区间是否全为1,并利用此信息,可使暴力复杂度达到O(N2^22M2^22),代码如下:import numpy as npclass Solution: def maximalRectangle(self, matrix: List[List[str]]) -> int: if matrix == []: return 0 rows, cols = len(matrix), len(matrix[0])

2020-12-26 23:28:27 102

原创 leetcode 387 扫描+延迟删除

解法一:扫两遍,第一遍存字典,第二遍遍历字典找到最小索引,代码如下:class Solution: def firstUniqChar(self, s: str) -> int: d = {} for i, c in enumerate(s): if c in d: d[c] = len(s) else: d[c] = i mi =

2020-12-23 09:53:41 110

原创 leetcode 714 股票dp

解法一:dpdp[i][0] = max(dp[i-1][0], dp[i-1][1]+prices[i])dp[i][1] = max(dp[i-1][1], dp[i-1][0]-prices[i]-fee)问题的核心是上述状态转移公式,第一条是好理解的,要吗保留,要么卖掉挣钱。第二条稍微难点,因为明显,买股票要花钱,为什么一定比持有股票便宜呢。这是因为,此处是0代表前几步肯定卖出去了。而这中间的差价是大于0的,能用这个差价赚钱,就可以更新了。完整代码如下:class Solution:

2020-12-17 10:44:59 71 1

原创 leetcode 738 贪心

这题要先找到最前面前一位比后面大的数字,这一位后面就都是9,这一位减一,前面的不变。class Solution: def monotoneIncreasingDigits(self, N: int) -> int: n = N power, ct = 1, -1 while N >= 10: num1 = N % 10 N //= 10 num2 = N % 10

2020-12-15 09:36:31 59 1

原创 leetcode 300 LIS 最长上升子序列 dp+贪心

首先是300,经典的最长上升子序列问题解法一:普通dp用dp做其实是很简单的,找到关键:对于每个元素,记录以这个元素为末尾的最长子序列长度。然后很容易就可想到递推公式,代码如下:class Solution: def lengthOfLIS(self, nums: List[int]) -> int: ret = 1 dp = [1 for _ in range(len(nums))] for i in range(1, len(nums)

2020-12-14 22:13:32 115

原创 leetcode 376 贪心 dp LIS

解法一:普通dp一看到子序列就想到dp,和LIS一样的套路,存以当前元素结尾的子序列长度。由于不知道前面序列的状态,需要再存一个status数组,看期待大的还是小的元素,代码如下:class Solution: def wiggleMaxLength(self, nums: List[int]) -> int: # 子序列问题 dp 设dp[i]是以他结尾一个元素,遍历之前的 dp = [1 for _ in range(len(nums))]

2020-12-14 21:28:49 87

原创 leetcode 49 哈希+字典+质数

解法一:容易想到用Counter计数然后作为key放进字典,但字典不能被hash,所以只能用桶再转tuple,代码如下:class Solution: def groupAnagrams(self, strs: List[str]) -> List[List[str]]: d = {} for s in strs: bm = [0 for _ in range(26)] for c in s:

2020-12-14 09:26:35 106

原创 leetcode 649 队列代替字典

解法一:字典看到题,啪的一下就出来了,但是做的其实不好。条件太多,挺笨的。class Solution: def predictPartyVictory(self, senate: str) -> str: d = [0, 0] tp_ct = [0, 0] tmp = '' while True: for s in senate: if s == 'R':

2020-12-11 15:09:48 103

原创 leetcode 62 组合数+动态规划

解法一:组合数一共有m-1和n-1种向下或向右的走法,用组合数排序from math import factorialclass Solution: def uniquePaths(self, m: int, n: int) -> int: return int(factorial(m+n-2)/(factorial(m-1)*factorial(n-1)))解法二:dp和爬楼梯问题类似,解法求和,啪的一下就过了class Solution: def un

2020-12-09 12:43:37 165 1

原创 leetcode 842 搜索剪枝

这个题还真挺简单的,值得记录的是这个题要求的数的范围在int内,但python的int函数其实是可以超过int范围的,所以咱们需要判断一下在(1<<31)-1范围内,另外,可以利用这一点,只搜索长度10以内的子串,是一个小的剪枝技巧。第二个点也是一个剪枝技巧,由于咱们需要先找到两个数,如果第一个数开头是0,那就不用搜索第二个数了。代码如下:class Solution: def splitIntoFibonacci(self, S: str) -> List[int]:

2020-12-08 09:48:03 193

原创 leetcode 621 堆+贪心维护(767升级版)

解法一:贪心堆这是我自己想的解法,先把任务变成字典,每次取剩余最多的任务,然后放入冷却堆,待到时间后取出。若优先队列里没元素了,专门处理冷却堆就行,这里采用了一个个排出再加进去的方法,代码如下:from queue import PriorityQueue, Queueclass Solution: def leastInterval(self, tasks: List[str], n: int) -> int: class t: def __in

2020-12-05 20:57:05 123

原创 7.2 FM Index Matching

首先注意,在BW矩阵中,相同前缀都是连续的,这是由排序决定的。第二个观察是最后一列出现在第一列前面(这还用观察?)寻找过程:从最短匹配的后缀开始,然后匹配越来越长的后缀。这里注意,前面存的C数组好像存的是每个字母开始的索引,不是个数,个数可以通过索引相减得要匹配模式aba,先找到最后一个a,4个,匹配到右边是两个,再到左边又可以得到了。整个过程还真是O(m)的。。很强啊。现在就可以回答count问题了,很简单。一共有两个可以匹配的。...

2020-12-04 23:35:29 419

原创 7.1 利用Wavelet做反转

回忆下之前是怎么反转BWT的,存第一列和最后一列,然后O(N)就可以用迭代的方式找到。现在,考虑如何利用学过的知识加速这一过程。可以对BWT建一颗Wavelet Tree,由于第一列和最后一列,字母相对顺序相同,所以左边的rank等于右边的rank。如何知道一个字母的个数?存或者高阶操作?上图为具体过程,可知字母个数是预存的。其中rank由于要找到对应节点,所以是log复杂度。但预存rank其实也不复杂,甚至会降低复杂度。。现在考虑如何做索引(indexing),即找到子串位置(终于来了)FM I

2020-12-04 23:02:25 183

原创 6.2 Wavelet Tree 复杂度

先考虑平衡Wavelet Tree,复杂度如下,易于理解对于上图,在我们已经存储最长的字符串的情况下,如何存储这些子串呢?

2020-12-04 22:20:55 682

原创 6.1 Wavelet Trees RSA操作

分割树常常用来分割‘值空间’,比如二叉搜索树,堆。这节课为了让字符串更好索引,用树来分割它的字母空间。如下图,我们可以不停分割直到剩余的是单一字母(即叶子节点)可以简化两个问题:1 你弄完这个还能搞索引吗?RSA操作2 这个树有多大?在此文中,旨在解决第一个问题,RSA还能用吗?指向之前提到的压缩问题(对A有影响)可以看到,在这个树里,每个节点都是bitvector,我们可以通过求解子问题,来merge到对字符串的RSA上图是字符串的RSA操作,把0和1换成对应字符就好。access操

2020-12-04 21:47:50 267

原创 5 位向量bitvectors RSA操作

位向量是一个非常简单的数据结构,里面只有0和1,比如我们存一个is_prime数组,就可以用位向量表示对应索引下是否是素数。DNA序列的one-hot表示: 也可以用bitvector接下来讨论三种对位向量的查询方式: RSA(Rank, Select, Access)基本上所有的查询操作都可以通过这三个解决,先看最简单的,Access,输入:索引 (or offset),输出:索引处的值,所以这只是单纯地用就行了。但有可能会变难,如果要对bitvector进行压缩,那要返回的就是解压后的值,需要

2020-12-04 19:58:32 211

原创 leetcode 659 类似dp O(N)时间+O(1)空间

这个题刚看到真的很头痛,但实际要找的是相邻元素间的关系。当我们看到一个元素的时候,我们可以知道,他一定要接在上一个元素的后面(除非上一个元素和他不是挨着的,比如当前元素是3,上一个是1)。那么我们此时就要考虑以上一个元素结尾的数组有多少,因为我们希望把当前元素加到上一个的后面。这种只考虑当前状态和上一状态的问题,可以叫做动态规划。首先,当遇到当前数时,我们最好把所有相同的数都提取出来,因为他们的上一元素都一样,我们可以批量处理。存储l1, l2, ln三个数表示以上一元素结尾的长度为1,2,>=3的

2020-12-04 17:06:24 53

原创 4 Burrow-Wheeler 变换

从k阶熵和0阶熵的比较中可以看出,k阶熵能储存更多的信息,从而具有更强大的压缩能力。而相比来说,0阶熵就有点太弱了。而BW变换可以作用于0阶熵之前,让0阶熵也拥有强大的能力。BW变换两种操作:旋转(rotation):把第一个字符放到字符串后面,可进行多次旋转操作,可看作每次操作将字符串分成两部分,交换前缀和后缀。对一个长度为n的串,共有n种可能notation:首先要知道,前缀小于字符串,比如as < ash(只是字典的约定,不是法律)我们定义一个$符号作为文本的终结符,让美元符号小于所有字

2020-12-03 23:41:40 535

原创 leetcode 204 经典素数O(N)线性筛

解法一:暴力 O(NN\sqrt{N}N​)看到一个数x,遍历[2, x]看是否整除,是最暴力的。此题还有个稍优雅解法,即遍历[2, x\sqrt{x}x​]。由于一个数如果能被整除,那一定还有另一个数作为商,而这两个不可能都大于x\sqrt{x}x​。直接这样做也会超时,可以只遍历奇数,并且保存存过的素数,只检查是否被素数整除即可,能勉强通过。from math import sqrtclass Solution: def countPrimes(self, n: int) -> in

2020-12-03 12:30:01 138

原创 leetcode 316 321 单调栈强化

之前做过402,也是单调栈,那个题可以选择去掉k个数字后的最小数,这种思想其实和本次的两个题是一样的,就是贪心的去掉前面较大的数字即可。而leetcode 768则是稍复杂的单调栈,pop的元素不是移除,而是合并,保留的是最大值,这个题是很值得回味的。回到316,这个题是一道难度超过medium的题,代码非常简单,思想不是那么容易。首先,与402类似,但咱们只能排出还能放进去的元素,所以要存个数组,放剩余的元素个数。第二个问题是,如果元素已在栈中,还要不要处理?答案很简单,不要。因为如果元素在栈中却没有被

2020-12-02 22:30:52 94

原创 leetcode 34 二分查找

本来是个很简单的题,前几天看视频也遇到了,两次二分就行,可是就那么亿点细节愣是整了半天。首先是移位,在已知要左移或右移时,应先改变left或者right再动指针。然后就是判别条件,应该是left <= right,这样能进行最后一次操作,之后就会退出,因为移位时是必定要动一位的,所以这种状态只能持续一次,代码如下:from math import ceilclass Solution: def searchRange(self, nums: List[int], target: int)

2020-12-01 14:41:53 117

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除