欢迎光临散文网 会员登陆 & 注册

红色重启-1

2022-06-24 03:56 作者:スレーブ_スレイヤー  | 我要投稿

尽量不要对自己的想法抱有什么期待,当然主观上的,感性的想法除外。


467. 环绕字符串中唯一的子字符串

把字符串 s 看作 "abcdefghijklmnopqrstuvwxyz" 的无限环绕字符串,所以 s 看起来是这样的:

  • "...zabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd...." 。

现在给定另一个字符串 p 。返回 s 中 不同 的 p 的 非空子串 的数量 。 


其实我的想法和官方的想法,在基础的部分是对上了的,比如确定一个起点(终点)和长度就能够确定一个子串。但在有了基础的认识以后,我的思路就开始往复杂的方向偏离了。


我惊人的发现了一个规律,一个字符串的子串数量,是满足n*(n+1)/2这个通项公式的。比如abcd,它的长度是4,4x5%2=10,所以abcd的子串的数量是10(包含自己)。

顺着这个思路,我想着把所有的子串的数量都算出来,再减去重合的部分就完事了。

然后问题的重心就来到了怎么算重合部分,其实到这里我已经走偏了,但我还是想顺着自己的思路来,毕竟如果这是考试或者真正的问题,我肯定还是会这么做。

此时问题变得复杂了,子串的重合有整整四种情况。但好在浪费了很多时间我还是想出来了。

但是有了新的问题,子串b如果和子串a重合,减去这个重合部分,此时子串c和ab都有重合部分的话,就会多减一次。于是我记录了每个子串已有的重合,如果多减了就把多减去的部分再加回来。

到这里我还没意识到不对,此时新的问题又出现了:加上多减的部分的逻辑是有漏洞的,简单说就是某些情况下会多加,于是我又需要新的逻辑和多余的变量来处理这个问题......

到这里我差不多没辙了,我没法保证浪费那么多脑力想出的办法解决了这个问题,程序就能正常运行,而且就算能,效率也是肉眼可见的低,大概还是会超时。


我想了一下,归根结底我还是在用软件开发的思路去做算法题,首先确定要实现的功能,然后寻找实现的方法,实现以后再看一下有没有什么不足,慢慢迭代。

软件的功能无非就是调一下API,基本的思路不可能出错,但做题很可能从一开始就饶了远路。

官方题解又是动态规划,我又栽到了DP上,一开始就想过是不是可以DP,但是一看字符串最长50000,马上放弃了这个想法。简而言之还是和上次一样,理解不够,思路太死。

试着理解一下官方的想法:

核心的要点是:

  1. 每个子串的结尾一定是26个字母中的一个。

  2. 结尾相同的子串,长度大的一定包含长度小的。

根据1和2可以想到3:

3. p的每一个子串,甚至子串的子串,都可以表示成结尾字符+长度的形式。

然后可以想到,只取某个字符结尾的子串的最大值,把26字符结尾的子串的长度相加,就是全部的组合数,因为取了最大值所以避免了重复的问题,即使一个子串长度超过26依旧满足上面的三点。


我还是学不会,官方题解总能一眼看到问题的本质,解法优雅的离谱。多少有脑筋急转弯的感觉,但是又不一样,总觉得应该是可以想出来的,可以依靠逻辑推出这个解法的。

简而言之,我还是傻逼,哪怕像它们一样满口高并低延大概率还是码农,只是调一下API傻逼也能做到,没什么好吹的。难的是解决未知问题的能力,这是一切的基础。







红色重启-1的评论 (共 条)

分享到微博请遵守国家法律