字节今年的校招薪资。。。

我们今天来看下字节跳动的校招薪资,整体来看薪资还是比较高的。非IT岗位(销售,运营等)< 测试  < 开发(前端,后端,移动端)< 算法。搞算法的工资相对来说是最高的,所以要想拿到更高的薪酬还是得搞算法,其实其他岗位也不低。

90198952a8da1532b4e4fcc4eeb5e621.jpeg

8c26f6fb68150ce36abdc3068fc42842.jpeg

56633598c3b0196517bbac2d521b9f7c.jpeg

dd478d72cb8813a0f393e7512f643746.jpeg

b518a408fcb862bbd8e93ff4b5f62376.jpeg

8ee3c29385a851f1f51487a1f021287e.jpeg

1e3c345588824ee7db0e7e0c7e455b0e.jpeg

我们主要来看一下IT岗,工作地点主要集中在北京,上海,深圳和杭州。基本上都是25k以上,最高的能达到34k,并且都是15薪,每月还有各种补贴,按照平均月薪30k来算的话,年包大概能达到45w,这对于刚毕业的学生来说还是很有诱惑力的。所以要想拿高薪,毕业之后进入字节也是一个非常不错的选择。

看完了字节的校招薪资,我们再来看一道关于字节的面试题。这题是LeetCode的第5题:最长回文子串。这题是字节的常考题,除了字节考过以外,华为,美团,米哈游等大厂也都考过,我们来看下。

1c1e46596919753da912fbe6e7821b82.png

a44a26c251e99c08360258666938e66b.png

问题描述

来源:LeetCode第5题

难度:中等

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

示例1:

输入:s = "babad"

输出:"bab"

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

示例2:

输入:s = "cbbd"

输出:"bb"

  • 1 <= s.length <= 1000

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

问题分析

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

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

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

我们定义二维数组dp[length][length],如果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]也必须相等,如下图所示。

832dcb409bef10a471c05dcb1df41fcc.png

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[left+1][right-1]的值,所以我们不能从上到下一行一行的遍历。因为在二维网格中dp[left+1][right-1]是在dp[left][right]的下一行,所以我们必须先计算dp[left+1][right-1]的值,才能计算dp[left][right]。

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

82835d4a3e9f07dd61408aad751fb9f3.png

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 < length; right++) {
        for (int left = 0; left < right; 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是回文子串,保存最长的回文子串。
            if (dp[left][right] && right - left + 1 > maxLen) {
                maxLen = right - left + 1;
                start = left;
            }
        }
    }
    // 截取最长的回文子串
    return s.substring(start, start + maxLen);
}

C++:

public:
    string longestPalindrome(string s) {
        // start表示最长回文子串开始的位置,为了后面截取。
        // maxLen表示最长回文子串的长度
        int start = 0, maxLen = 1;
        int length = s.size();
        vector<vector<int>> dp(length, vector<int>(length));
        for (int right = 1; right < length; right++) {
            for (int left = 0; left < right; left++) {
                // 如果两种字符不相同,肯定不能构成回文子串。
                if (s[left] != s[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是回文子串,保存最长的回文子串。
                if (dp[left][right] && right - left + 1 > maxLen) {
                    maxLen = right - left + 1;
                    start = left;
                }
            }
        }
        // 截取最长的回文子串
        return s.substr(start, maxLen);
    }

-------------------------end-------------------------

笔者简介

博哥,真名:王一博,毕业十多年,《算法秘籍》作者,专注于数据结构和算法的讲解,在全球30多个算法网站中累计做题2000多道,在公众号中写算法题解700多题,对算法题有自己独特的解题思路和解题技巧,喜欢的可以给个关注,也可以下载我整理的1000多页的PDF算法文档。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

数据结构和算法

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值