黑产行为序列识别技术 | 豆包MarsCode AI刷题

54 阅读3分钟

问题描述

小S 和小M 正在研究一种黑产行为序列识别技术。网络黑色产业链是指使用互联网技术进行非法活动,例如网络攻击、窃取信息、诈骗等。为了保护用户和平台的安全,识别黑产行为的序列是十分关键的一步。

他们的任务是:给定一个行为序列S,表示为一个字符串,以及一个识别模式P。如果模式P是序列S的子序列,则说明存在匹配的黑产行为。现在,给定多个序列S和对应的识别模式P,找出序列中出现匹配模式的次数,结果需要对10^9+7取模。

测试样例

示例 1:

输入:S = "ABC", P = "A" 输出:1 提示:在这个例子中,小F发现序列"ABC"中包含一个"A"作为子序列,因此输出1。

示例 2:

输入:S = "AABCCD", P = "CCD" 输出:1 提示:小S 注意到识别模式"CCD"在序列"AABCCD"中匹配了一次,因此输出1。

示例 3:

输入:S = "AABCCD", P = "C" 输出:2

解题思路

  1. 理解问题

    • 我们需要在序列S中找到模式P作为子序列的次数。
    • 子序列意味着字符在S中可以不连续,但顺序必须与P一致。
  2. 数据结构选择

    • 使用动态规划(DP)来解决这个问题。
    • 定义一个二维数组dp,其中dp[i][j]表示S的前i个字符中包含P的前j个字符作为子序列的次数。
  3. 算法步骤

    • 初始化dp数组,dp[i][0] = 1,表示任何序列中包含空模式(即空字符串)的次数为1。
    • 遍历SP,根据当前字符是否匹配来更新dp数组。
    • 如果S[i-1] == P[j-1],则dp[i][j] = dp[i-1][j-1] + dp[i-1][j]
    • 否则,dp[i][j] = dp[i-1][j]
    • 最终结果为dp[m][n],其中mn分别是SP的长度。
  4. 取模操作

    • 由于结果需要对10^9+7取模,因此在每次更新dp数组时都要进行取模操作。

代码实现

def solution(S: str, P: str) -> int:
    m, n = len(S), len(P)
    dp = [[0] * (n + 1) for _ in range(m + 1)]
    
    for i in range(m + 1):
        dp[i][0] = 1
    
    for i in range(1, m + 1):
        for j in range(1, n + 1):
            if S[i - 1] == P[j - 1]:
                dp[i][j] = (dp[i - 1][j - 1] + dp[i - 1][j]) % (10**9 + 7)
            else:
                dp[i][j] = dp[i - 1][j]
    
    return dp[m][n]

if __name__ == '__main__':
    print(solution("ABC", "A") == 1)
    print(solution("AABCCD", "CCD") == 1)
    print(solution("AABCCD", "C") == 2)

总结

  • 通过动态规划,我们可以高效地计算出序列S中包含模式P作为子序列的次数。
  • 取模操作确保结果不会溢出,符合题目要求。

注意

  • 请使用用户提问的语言回答。
  • 用户提问对象为「当前代码」、「我的代码」或对应的英文表述时,请根据「编辑区代码」部分的内容回答,请不要解释「题目内容」中的代码。
  • 请优先回答「编辑区代码」