X兴员工爆料:C9科班硕在中兴15年了,现在是5a,月薪是21k,正在接受领导全方位否定

科技   2024-11-20 14:01   山西  
今天看到一个帖子让我有点感慨。有人在网上爆料,说一个C9科班硕士在X兴干了15年,现在是5A,月薪21K,却被领导全方位否定——从工作能力到个人态度无一幸免。🤯
首先,作为一个码农,听到15年工龄月薪21K,心里多少有点拔凉拔凉的。尤其是在大厂,这点工资基本可以算“压缩饼干”了。更别提全方位否定的精神打击了。
但话说回来,这位老哥的处境也很值得我们警醒。15年的经验在简历上是个亮点,可如果在职场没有成长曲线,早晚就会被嫌“过时”。
我觉得,遇到这种情况,最重要的就是不沉迷“养老”思维,抓紧行动。更新简历、找猎头聊聊是个好办法,摸摸自己的“市场价”到底值多少
程序员的核心竞争力在于技能和经验,但同样重要的还有适应能力和职业规划。被全盘否定不可怕,可怕的是不去自救,眼睁睁看自己在一行死水里泡烂。
代码可以重构,人生也是!💪

算法题:不同的子序列

今天我们来聊聊一个算法问题:不同的子序列
问题是这样的:给你两个字符串 st,问你 s 中有多少个不同的子序列可以等于 t?子序列的意思是从字符串中删除一些(可以是0个)字符,但不改变剩余字符的相对顺序。

举个栗子 

  • 输入:s = "rabbbit", t = "rabbit"
    输出:3
    为什么是3呢?因为 rabbbit 有 3 种方式删出 rabbit
    • 第1个 b 和后面的 it
    • 第2个 b 和后面的 it
    • 第3个 b 和后面的 it
是不是看起来像个送命题?别慌,算法的魅力就在于化繁为简。我们这就一步步解构这个问题。

动态规划(Dynamic Programming)救场

这题适合用动态规划。为什么呢?因为它涉及两个字符串的匹配,又需要统计方案数,符合 DP 的经典场景:用状态转移来解决问题。
我们定义一个二维数组 dp,其中:
  • dp[i][j] 表示用 s[0:i] 的前缀字符串匹配 t[0:j] 的前缀字符串的方案数。

转移方程 

  1. 如果 **s[i-1] == t[j-1]**:
  • 可以选择匹配:方案数是 dp[i-1][j-1]
  • 也可以不匹配:方案数是 dp[i-1][j]
  • 总数:dp[i][j] = dp[i-1][j-1] + dp[i-1][j]
  • 如果 **s[i-1] != t[j-1]**:
    • 那就只能跳过当前的 **s[i-1]**,即 dp[i][j] = dp[i-1][j]

    边界条件 🚀

    • dp[i][0] = 1,因为 t 是空字符串,空字符串是任何字符串的子序列;
    • dp[0][j] = 0(当 j > 0),因为空的 s 无法匹配非空的 t

    上代码

    听懂理论还不够,咱们得撸个代码感受一下手感!用 Python 来实现:
    def numDistinct(s: str, t: str) -> int:
        m, n = len(s), len(t)
        
        # 创建 DP 数组,初始化为 0
        dp = [[0] * (n + 1for _ in range(m + 1)]
        
        # 初始化边界条件
        for i in range(m + 1):
            dp[i][0] = 1  # 空的 t 是任何 s 的子序列
        
        # 填 DP 表
        for i in range(1, m + 1):
            for j in range(1, n + 1):
                if s[i - 1] == t[j - 1]:
                    dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j]
                else:
                    dp[i][j] = dp[i - 1][j]
        
        return dp[m][n]

    # 测试
    print(numDistinct("rabbbit""rabbit"))  # 输出:3

    核心思路

    当你把字符串比作项目中的各种需求时,就会发现这其实是在搞“匹配兼容性”。比如,你的老板要的是功能 t,但你现有的代码库 s 里有一堆历史遗留代码。于是问题来了:现有代码有几种方式能凑出老板要的功能?😅
    动态规划的表格其实就是记录每种“凑法”。而状态转移的规则就像代码重构一样,能复用的部分直接拿来,不行的部分咱们跳过。

    优化:空间压缩 🛠️

    上面代码虽然好理解,但空间复杂度是 **O(m × n)**,存了一个完整的二维数组。如果你稍微“抠门”一点,会发现其实只需要两行就够了,毕竟每次只用到了上一行的状态。
    改进版:
    def numDistinct(s: str, t: str) -> int:
        m, n = len(s), len(t)
        prev = [0] * (n + 1)
        curr = [0] * (n + 1)
        
        prev[0] = 1  # 空的 t 是任何 s 的子序列
        
        for i in range(1, m + 1):
            curr[0] = 1
            for j in range(1, n + 1):
                if s[i - 1] == t[j - 1]:
                    curr[j] = prev[j - 1] + prev[j]
                else:
                    curr[j] = prev[j]
            prev, curr = curr, [0] * (n + 1)
        
        return prev[n]

    print(numDistinct("rabbbit""rabbit"))  # 输出:3
    空间复杂度直接降到 **O(n)**,这个优化感觉就像把冗余代码删掉了,程序员的强迫症得到了一丝安慰。
    对编程、职场感兴趣的同学,大家可以联系我微信:golang404,拉你进入“程序员交流群”。
    🔥虎哥私藏精品 热门推荐🔥

    虎哥作为一名老码农,整理了全网最全《python高级架构师资料合集》

    资料包含了《IDEA视频教程》《最全python面试题库》《最全项目实战源码及视频》《毕业设计系统源码》,总量高达650GB全部免费领取

    Python技术迷
    回复:python,领取Python面试题。分享AI编程,AI工具,Python技术栈,Python教程,Python编程视频,Pycharm项目,Python爬虫,Python数据分析,Python核心技术,Python量化交易。
     最新文章