变得更好

一切朝着好的方向前进。

迷惑时读书,“躲进小楼成一统,管他冬夏与春秋”,从书籍中汲取营养,与高人交谈,真能解惑与传道。今年读了很多大部头的书,越来越发觉罗曼罗兰那句名言的价值:世界上只有一种真正的英雄主义,那就是认清生活的真相后依然热爱生活。莫言是如此,当年明月也是如此。莫言在《晚熟的人》中说,“真正的强大不是忘记,而是接受 —— 接受分道扬镳,接受世事无常,接受孤独挫败”,说的也是这个意思。当年明月在《明朝那些事儿》的最后说“无论多么绝望,无论有多悲哀,每天早上起来,都要对自己说,这个世界很好,很强大。”他们说的都是一个意思:生命本无意义,而且常常是苦多于乐的,但这就是生活。这就是生命本来的面目,爱生活,尊重生命,然后以一种积极的心态,努力实践的精神,让自己变得更好,然后以自己微弱的光感染身边的人,这本身就是生命的意义。

“好”的焦虑

经济下行、中年危机、失业担忧、未来无望,漫长的职业期与看似即将结束的职业生涯…

看网上的文章,今年失业的人很多,gap时间也很长。在职的担心被裁,失业的感叹工作不好找,有点积蓄的不敢消费;年纪小的不敢想35岁的生活,过了35岁的感叹找工作难度陡升;有人劝你别创业,有人劝你开辟第二职业,有人劝你少花钱…大家仿佛时间与金钱的极限拉扯中,陷入深深的焦虑。

最近小区做旧房改造,突然多了许多工人,小区的小饭馆也突然人多了起来,三五成群,大口吃饭,大口喝酒。有些吃完了,坐在台阶上,或看着视频,或跟家人聊天,或劳累,或满足。

喜欢观察身边来来往往的人,对于这些工人,他们焦虑吗?有的年纪有不大,大多也像是上有老,下有小的,那些焦虑的问题,他们应该也有。他们学历不会高,挣得也不多,干得很辛苦,背井离乡,大概率也不会写什么文章,看什么文章。

做一个简单的逻辑推断:做脑力劳动的人比体力劳动的人多,挣得也多。能想焦虑的问题却是少数,还是那些挣得多,又有想法的人。仔细想想,能焦虑的人已经不知道胜过别人多少了。换句话来说,当你焦虑时,你已经领先很多了。好好珍惜手头的工作,好好珍惜下一份工作,你的焦虑在别人看来,只不过是一种矫情。

历史的忧伤

一页史书,寥寥数笔,纵贯人物的一生。

同时代的芸芸众生,永远消失在历史里,不会有人记得。

他们有来过吗?他们的一生是快乐的吗?他们有想过这样的问题吗?

我们终将消失在历史里,有幸者,或许能被史书记上一笔,但翻过他那一页,同时代的人的一生也过去了。

–读《明朝那些事儿》有感

坚持半年

三个月的时间过去了,今天是7月2日,写下“半年”篇。

没看小视频,反正也没什么影响。这几个月工作上有点不太顺,和自己的预想有些差距,只能好好蓄力了。

看书的计划基本提前完成了,后面主要精力会放在数学与备考上,工作上还是要精进。

虽然时常焦虑,但也坦然接受。大环境如此,不必太过苛求自己。

过好每一刻,喜迎阳光!

坚持一个季度

距离上一篇过去了一个多月,今天是4月3号,节前的工作日,来写下“季”篇。

其实没有可写的,在过去的一个多月,反正是没看小视频,感觉那个东西从自己的生活中消失了。

看了十二本书,有些书是之前看过的,收个尾;有些书读起来费劲,匆匆掠过;两本传记《邓稼先传》和《苏东坡》,出自两位女性之手,文笔细腻,感情真挚,回味无穷,感慨万千。

下一篇可能要等到“半年”篇了,接下来三个月的时间,可能主要精力会在工作上,把几个方向的视频看完,把计划的项目完成了,足矣!

坚持一个月

2025年已经过去一个多月了。我的远离短视频计划从”周“跨到一个更大的计量单位了,下一步就是向”季“出发了。

在这个春节假期,读了三本书,传记、教育和历史各一本,读完有种酣畅淋漓的感觉。最近,晚上会看些经济学的书,确实有意思,解决了很多疑问,打开了许多思路。

坚持读书,坚持学习,坚持到3月份结束来写”季“篇!

新年flag

数字时代,越来越难以完成一个简单的目标了。

过去的一年,简单回顾,短视频吞噬了太多的时间。开发这一技术的人太了解人性的弱点了,拇指的上滑有无穷的魔力,不断刺激大脑中的兴奋区,让人欲罢不能。我自认为还是一个有自控力的人,“就放松一下”,“就看一个小时”…,很遗憾,没有胜出过。有时候工作确实累了,想通过小视频来放松一下,而实际情况是,看完之后有深深的自责感,看了很多,发现有收获的不多。而且惊奇地发现,最近看的内容和一年前的完全不一样啊,难道是一年前的博主不更新了?我还特地去搜了下,发现都还在,只是“算法”不给我推荐了。那我岂不是被控的小鼠?

趁着新的一年到来,趁着这个契机,立下一个新年flag–远离短视频。那省下的时间干吗?看paper,看教学视频,读书,学语言。初试了几天,突然发现时间变多了,学习了很久,抬头看钟,发现未到11点,有点豁然开朗的感觉。短视频倾向于短平快的内容,像一些艰深的、系统的、综合的知识,是需要很长的静下来的时间来学习的,而恰恰是这些知识,才是我们个人能力、谈吐、学识的来源。

一星期纪念,感觉很轻松,一点难受的感觉都没有,加油,坚持!

重启

好久没有写东西,网站都有点落灰了!

看看之前写的东西,当时觉得有点微不足道的东西,现在读起来也有些许新意。记述心路历程,留下成长足迹。

不管怎样,动手写起来!

最长回文子串

这是算法的第5题,描述如下:

给定一个字符串s, 找到s中最长的回文子串。你可以假设s的最大长度为1000.

示例1:

输入:”babad”

输出:”bab”

注意:”aba”也是一个有效答案。

示例2:

输入:”cbbd”

输出:”bb”

此题难度:中等,通过率30%过一点。

题解转自官方解法,链接如下:

转自:https://leetcode-cn.com/problems/longest-palindromic-substring/solution/zui-chang-hui-wen-zi-chuan-by-leetcode-solution/

方法一:动态规划

思路与算法

对于一个子串而言,如果它是回文串,并且长度大于 2,那么将它首尾的两个字母去除之后,它仍然是个回文串。例如对于字符串 “ababa”,如果我们已经知道

“bab” 是回文串,那么“ababa” 一定是回文串,这是因为它的首尾两个字母都是 “a”。

根据这样的思路,我们就可以用动态规划的方法解决本题。我们用P(i,j) 表示字符串 s 的第 i 到 j 个字母组成的串(下文表示成 s[i:j])是否为回文串:
P(i,j) = true if 如果子串 Si…Sj 是回文串;

P(i,j) = false 其他情况。

这里的「其它情况」包含两种可能性:
s[i,j] 本身不是一个回文串;
i>j,此时 s[i,j] 本身不合法。

那么我们就可以写出动态规划的状态转移方程:
P(i,j)=P(i+1,j−1)∧(S_i == S_j)

也就是说,只有 s[i+1:j−1] 是回文串,并且s 的第i 和 j个字母相同时,s[i:j] 才会是回文串。

上文的所有讨论是建立在子串长度大于 2 的前提之上的,我们还需要考虑动态规划中的边界条件,即子串的长度为 1 或 2。对于长度为1 的子串,它显然是个回文串;对于长度为 2 的子串,只要它的两个字母相同,它就是一个回文串。因此我们就可以写出动态规划的边界条件:

P(i,i)=true

P(i,i+1)=(Si==Si+1)

根据这个思路,我们就可以完成动态规划了,最终的答案即为所有 P(i,j)=true 中 j−i+1(即子串长度)的最大值。注意:在状态转移方程中,我们是从长度较短的字符串向长度较长的字符串进行转移的,因此一定要注意动态规划的循环顺序。

复杂度分析

时间复杂度:
O(n^2),其中 n 是字符串的长度。动态规划的状态总数为 O(n^2),对于每个状态,我们需要转移的时间为 O(1)。

空间复杂度:
O(n^2),即存储动态规划状态需要的空间。

方法2:中心扩展算法

思路与算法

我们仔细观察一下方法一中的状态转移方程:

P(i,j) = true;

P(i, i+1) = (S_i == S_i+1);

P(i,j)=P(i+1,j−1)∧(S_i == S_j)

出其中的状态转移链:
P(i,j)←P(i+1,j−1)←P(i+2,j−2)←⋯←某一边界情况

可以发现,所有的状态在转移的时候的可能性都是唯一的。也就是说,我们可以从每一种边界情况开始「扩展」,也可以得出所有的状态对应的答案。

边界情况即为子串长度为 1 或 2 的情况。我们枚举每一种边界情况,并从对应的子串开始不断地向两边扩展。如果两边的字母相同,我们就可以继续扩展,例如从 P(i+1,j−1) 扩展到 P(i,j);如果两边的字母不同,我们就可以停止扩展,因为在这之后的子串都不能是回文串了。

聪明的读者此时应该可以发现,「边界情况」对应的子串实际上就是我们「扩展」出的回文串的「回文中心」。方法二的本质即为:我们枚举所有的「回文中心」并尝试「扩展」,直到无法扩展为止,此时的回文串长度即为此「回文中心」下的最长回文串长度。我们对所有的长度求出最大值,即可得到最终的答案。

复杂度分析

时间复杂度:O(n^2),其中 n 是字符串的长度。长度为 1 和 2 的回文中心分别有 n 和 n−1 个,每个回文中心最多会向外扩展 O(n) 次。

空间复杂度:O(1)。

代码如下(将两个题解放在一个文件里,分别为_s1和_s2):

def longestPalindrome_s1(s):
    n = len(s)
    dp = [[False] * n for _ in range(n)]
    ans = ""
    for l in range(n):
        for i in range(n):
            j = i + l
            if j >= len(s):
                break
            if l == 0:
                dp[i][j] = True
            elif l == 1:
                dp[i][j] = (s[i] == s[j])
            else:
                dp[i][j] = (dp[i+1][j-1] and s[i] == s[j])
            if dp[i][j] and l + 1 > len(ans):
                ans = s[i:j+1]
    return ans


print(longestPalindrome_s1("fsafsdabbad"))

########################################################################

def expandAroundCenter(s,left,right):
    while left >= 0 and right < len(s) and s[left] == s[right]:
        left -= 1
        right += 1
    return left + 1, right - 1

def longestPalindrome_s2(s):
    start, end = 0, 0
    for i in range(len(s)):
        left1, right1 = expandAroundCenter(s, i, i)
        left2, right2 = expandAroundCenter(s, i, i+1)
        if right1 - left1 > end - start:
            start, end = left1, right1
        if right2 - left2 > end - start:
            start, end = left2, right2
    return s[start: end+1]

print(longestPalindrome_s2("fsafsdabbad"))

作者:LeetCode-Solution

链接:https://leetcode-cn.com/problems/longest-palindromic-substring/solution/zui-chang-hui-wen-zi-chuan-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。