专栏名称: IT服务圈儿
关注互联网前沿资讯,提供最实用的学习资源。我们是有温度、有态度的IT自媒体平台。
目录
相关文章推荐
手游那点事  ·  春节期间,10家游戏公司宣布了裁员 ·  4 天前  
手游那点事  ·  今天,率土团队单机新作公开Steam页面 ·  3 天前  
51好读  ›  专栏  ›  IT服务圈儿

现在背调手段越来越高明了。

IT服务圈儿  · 公众号  ·  · 2025-01-13 17:30

正文

来源丨经授权转自 数据结构和算法(ID:sjjghsf)

作者丨博哥


最近一网友在入职之前遇到公司背调,问的还那么详细,关键被问的人还那么配合。我觉得招一个产品经理不至于,又不是啥高管。之前我找工作的时候也遇到过背调,不过查的是社保记录,主要是判断工作履历是否真实,是否真的在那家公司干过,个人能力是查不到的。


背调现在也是屡见不鲜,之前有一个同事离职之后空闲了半年多,背调的时候填我的手机号,临时给我打电话告诉我该怎么说,结果不到10分钟hr真打过来了,其实这种背调就是 往好的夸 ,最后也成功入职,所以大家在工作中最好要有一个玩的特别好的同事,以后找工作遇到背调可以帮你说两句。但有的人离职是因为和领导关系搞的不好,有的背调公司要填领导的联系方式,这种背调就很坑了。







--------------下面是今天的算法题--------------


来看下今天的算法题,这题是LeetCode的第5题:最长回文子串。


问题描述



来源:LeetCode第5题
难度:中等

给你一个字符串 s,找到 s 中最长的回文子串。如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。

示例1:

输入 :s = "babad"

输出 :"bab"

解释 :"aba" 同样是符合题意的答案。

示例2:

输入 :s = "cbbd"

输出 :"bb"


  • 1 <= s.length <= 1000

  • s 仅由数字和英文字母组成


问题分析



这题是让找出字符串 s 的最长回文子串, 最简单的一种解决方式就是截取字符串 s 的所有子串 ,然后判断它的所有子串哪些是回文串,保存最长的回文串即可,这种解法虽然简单,但时间复杂度比较高。

还一种解决方式就是中心扩散法 ,我们需要以每一个字符为中心往两边扩散,查找并记录最长的回文子串。查找完之后下一步我们还要以下一个字符为中心往两边扩散进行查找,这样效率也不是很高。这个时候我们可以对他进行优化,使用马拉车算法。

所以这题的最经典解法还是 马拉车算法 ,关于马拉车算法大家可以看下 《算法秘籍》 中第 13 章的13.2 马拉车算法,这里就不在介绍。我们这里主要讲另外一种解决方式,动态规划。

我们定义二维数组dp[][],如果dp[left][right]为true,则表示子串s[left,right]是回文子串,如果dp[left][right]为false,则表示子串s[left,right]不是回文子串。


如果 dp[left][right]是回文子串,首先 dp[left+1][right-1]必须是回文子串,并且 s[ left]和s[right]也必须相等,如下图所示。


1,如果s [ left ]! =s[ right] ,子串s[left,right]不可能是回文子串。

2, 如果 s [ left ]= =s[ right] 子串s[left,right ] 能不能构成回文子串还需要进一步判断:

2.1,如果left==right,也就是说只有一个字符,我们认为它是回文子串。即dp[left][right]=true(left==right)

2.2,如果right-left<=2,类似于"aa",或者"aba",中间最多只有一个字符,我们也认为它是回文子串,即dp[left][right]=true(right-left<=2)

2.3,如果right-left>2,需要判断dp[left+1][right-1]是否是回文子串,才能确定dp[left][right]是否为true还是false。 即dp[left][right]=dp[left+1][right-1]


所以我们可以找出递推公式如下:

dp[left][right]=s[left]==s.[right]&&dp[left+1][right-1]
这里要注意,因为 dp[left][right]的值要依赖 dp[l e ft+1][right-1]的值,所以不能从上到下一行一行的遍历。因为在二维网格中 dp[l e ft+1][right-1]是在 dp[lef t][right]的下一行,所以必须先计算 dp[l e ft+1][right-1] 的值,才能计算 dp[lef t][right]。

遍历方式有多种,可以从左到右一列一列的遍历,也可以从下到上一行一行的遍历,还可以从对角线往右上角一行一行的遍历, 无论哪种方式,都要保证在计算dp[left][right]的时候,dp[left+1][right-1]的值一定是计算过的

JAVA:
public String longestPalindrome(String s) {
    // start表示最长回文子串开始的位置,为了后面截取。
    // maxLen表示最长回文子串的长度
    int start = 0, maxLen = 1;
    int length = s.length();
    boolean[][] dp = new boolean[length][length];
    for (int right = 1; right         for (int left = 0; left             // 如果两种字符不相同,肯定不能构成回文子串。
            if (s.charAt(left) != s.charAt(right))
                continue;
            // 下面是s[left]和s[right]两个字符相同情况下的判断。
            if (right - left <= 2) {
                // 类似于"a","aa"和"aba",也是回文子串。
                dp[left][right] = true;
            } else {
                // 类似于"a******a",要判断他是否是回文子串,只需要
                // 判断"******"是否是回文子串即可。
                dp[left][right] = dp[left + 1][right - 1];
            }
            // 如果字符串从left到right是回文子串,保存最长的回文子串。






请到「今天看啥」查看全文