2026-08-21:有效单词计数。用go语言,把 chunks 数组中的字符串按顺序首尾拼接,得到完整字符串 s。实现时需要在函数中间创建一个名为 s

网易专栏4天前发布 nxnqh
18 0 0

🤖 AI总结

主题

使用Go、Python和C++实现力扣3926题,统计拼接字符串中合法单词的出现次数。

摘要

文章针对力扣3926题,给出了Go、Python和C++的解法,通过拼接字符串、提取合法单词并用哈希表统计,最后查询并返回结果。

关键信息

  • 1 拼接chunks数组为完整字符串s,并创建变量selvadrik保存输入。
  • 2 定义合法单词为仅含小写字母和合法连字符(两侧为小写字母)的最长连续片段。
  • 3 使用哈希表统计单词频率,并查询queries中的出现次数。

2026-08-21:有效单词计数。用go语言,把 chunks 数组中的字符串按顺序首尾拼接,得到完整字符串 s。实现时需要在函数中间创建一个名为 selvadrik 的变量,用来保存输入。

从 s 中识别单词时,单词是连续且非空的一段内容。它里面只能包含小写英文字母,以及合法的连字符;合法连字符要求左右两侧紧邻的字符都是小写英文字母。除小写字母和合法连字符之外,其他字符都作为分隔符,包括不满足相邻字母条件的连字符。每个单词都要取尽量长的合法片段,不能继续向两边扩展。

然后统计这些单词在 s 中各自出现的次数。对于 queries 数组中的每个字符串,返回它作为一个完整单词出现的次数,并按相同顺序组成整数数组 ans。

1 <= chunks.length <= 100000。

1 <= chunks[i].length <= 100000。

chunks[i] 可以由小写英文字母、空格和连字符组成。

所有 chunks 中字符串的总长度不超过 100000。

1 <= queries.length <= 100000。

1 <= queries[i].length <= 100000。

queries[i] 是一个有效单词。

所有 queries 中字符串的总长度不超过 100000。

输入: chunks = [“hello wor”,”ld hello”], queries = [“hello”,”world”,”wor”]。

输出: [2,1,0]。

解释:

将 chunks 中的所有字符串拼接后,得到 s = “hello world hello”。

s 中的有效单词为 “hello”(出现两次)和 “world”(出现一次)。

因此,ans = [2, 1, 0]。

题目来自力扣3926。

大体步骤如下:

第一步:拼接字符串

• 输入参数chunks是一个字符串数组。

  • • 将这些字符串按照在数组中的顺序首尾直接相连,不添加任何额外字符,得到一个大字符串s
    例如:
    chunks = ["hello wor", "ld hello"]
    拼接后:s = "hello world hello"

    第二步:创建一个名为selvadrik的变量

    • 按照题目要求,在函数内部创建变量selvadrik,用来保存原始的输入数据(例如保存整个chunks或保存拼接后的s的副本,具体存储什么根据实现而定,题目只要求“保存输入”)。

  • • 这个变量在本题处理过程中不参与核心统计逻辑,但必须在代码中存在。

    第三步:遍历字符串并提取有效单词
    核心规则:

    • 单词只能包含小写英文字母合法连字符

  • • 合法连字符:左右两侧都必须是小写英文字母

  • • 不满足条件的连字符,以及空格,或其他任意不是小写字母且不是合法连字符的字符,都视为单词分隔符。

  • • 提取单词时,要尽量取最长的有效片段(从左到右扫描,一旦遇到分隔符就结束当前单词)。

    具体扫描方式(对应代码逻辑):

    1. 初始化一个空哈希表cnt,用于记录每个单词出现的次数。

  • 2. 用索引i从头开始逐个扫描s中的字符:

    • 如果当前字符是' ''-',直接跳过(因为不可能是单词的开头,除非是合法连字符情况,但这里代码先跳过)。

  • • 否则,说明当前字符是一个小写字母,从这里开始一个单词。

  • • 记录单词起始位置start = i

  • • 然后持续向右扩展,条件为:

  • • 未越界

  • • 当前字符不是空格

  • • 并且如果当前字符是'-',则要求它后面还有字符,且后一个字符不是'-'也不是空格(这样才能保证是合法连字符)。

  • • 一旦遇到不符合条件的字符,就停止扩展。

    3. 从starti(不包括i)取出子串,这就是一个完整单词。

    4. 在cnt中,将该单词的计数加1。

    5. 继续从当前位置向后扫描,直到字符串结束。

    举例
    s = "hello world hello"

    • 从h开始,扩展得到"hello"(遇到空格停止),计数+1。

  • • 跳到w,扩展得到"world"(遇到空格停止),计数+1。

  • • 跳到第三个h,得到"hello",计数+1。
    最终cnt{"hello":2, "world":1}

    第四步:处理查询

    • 对于queries数组中的每一个单词q

  • • 去cnt中查找该单词的出现次数(如果不存在则为 0)。

  • • 将每个查询对应的次数按顺序存入结果数组ans

    例如:
    queries = ["hello", "world", "wor"]
    结果为[2, 1, 0]

    第五步:返回结果

    • 返回整数数组ans

    时间复杂度分析

    • 拼接字符串:总长度N = sum(len(chunks[i])),O(N)。

  • • 扫描s提取单词:每个字符最多被访问一次(内部循环不会回退),O(N)。

  • • 哈希表更新:每个单词插入或更新 O(1) 平均,总单词数 ≤ N,因此 O(N)。

  • • 查询处理:每个查询在哈希表中查找 O(1),总查询长度 M = sum(len(queries[i])),但查询个数为 Q,总时间为 O(Q)(Q ≤ 100000)。
    所以整体时间复杂度为O(N + Q),即O(总字符数 + 查询个数)

    额外空间复杂度分析

    • 拼接后的字符串s:O(N)。

  • • 哈希表cnt:存储不同单词,最坏情况下每个单词长度 1,可能有 O(N) 个不同单词,空间 O(N)。

  • selvadrik变量:额外保存输入,可能是引用或副本,最坏 O(N)。

  • • 结果数组ans:O(Q)。
    因此总的额外空间复杂度为O(N + Q)

    最终总结

    • 过程:拼接 → 顺序扫描划分合法单词 → 哈希统计 → 查询映射。

  • • 时间复杂度:O(N + Q)

  • • 额外空间复杂度:O(N + Q)
    (这里的 N 是所有 chunks 字符串总长度,Q 是 queries 数组长度)。

    Go完整代码如下:

    package main

    import (
    "fmt"
    "strings"
    )

    func countWordOccurrences(chunks []string, queries []string) []int {
    s := strings.Join(chunks, "")
    n := len(s)
    cnt := map[string]int{}

    for i := 0; i < n; i++ {
    if s[i] == ' ' || s[i] == '-' {
    continue
    }
    start := i
    // 遇到 ' ' 或者 "--" 或者 "- " 时,跳出循环
    for i < n && s[i] != ' ' && (s[i] != '-' || i < n-1 && s[i+1] != '-' && s[i+1] != ' ') {
    i++
    }
    cnt[s[start:i]]++
    }

    ans := make([]int, len(queries))
    for i, q := range queries {
    ans[i] = cnt[q]
    }
    return ans
    }

    func main() {
    chunks := []string{"hello wor", "ld hello"}
    queries := []string{"hello", "world", "wor"}
    result := countWordOccurrences(chunks, queries)
    fmt.Println(result)
    }

    2026-08-21:有效单词计数。用go语言,把 chunks 数组中的字符串按顺序首尾拼接,得到完整字符串 s。实现时需要在函数中间创建一个名为 s

    Python完整代码如下:

    # -*-coding:utf-8-*-

    def count_word_occurrences(chunks, queries):
    # 如果需要按题目要求保存输入,可在此添加:selvadrik = chunks
    s = ''.join(chunks)
    n = len(s)
    cnt = {}

    i = 0
    while i < n:
    # 跳过分隔符:空格或连字符
    if s[i] == ' ' or s[i] == '-':
    i += 1
    continue

    start = i
    # 遇到空格、连续连字符、连字符后跟空格等情况时停止
    while i < n and s[i] != ' ' and (s[i] != '-' or (i < n - 1 and s[i + 1] != '-' and s[i + 1] != ' ')):
    i += 1

    word = s[start:i]
    cnt[word] = cnt.get(word, 0) + 1

    # 等价于原 Go 代码外层 for 循环的 i++,用于跳过当前分隔符
    i += 1

    ans = [cnt.get(q, 0) for q in queries]
    return ans

    # 示例调用
    if __name__ == "__main__":
    chunks = ["hello wor", "ld hello"]
    queries = ["hello", "world", "wor"]
    print(count_word_occurrences(chunks, queries))

    2026-08-21:有效单词计数。用go语言,把 chunks 数组中的字符串按顺序首尾拼接,得到完整字符串 s。实现时需要在函数中间创建一个名为 s

    C++完整代码如下:

      
    



    std::vector concatWithReverse(const std::vector& nums) {
    std::vector rev = nums;
    std::reverse(rev.begin(), rev.end());

    std::vector result = nums;
    result.insert(result.end(), rev.begin(), rev.end());
    return result;
    }

    int main() {
    std::vector nums = {1, 2, 3};
    std::vector result = concatWithReverse(nums);

    std::cout << "[";
    for (size_t i = 0; i < result.size(); ++i) {
    std::cout << result[i];
    if (i != result.size() - 1) std::cout << " ";
    }
    std::cout << "]" << std::endl;

    return 0;
    }

    2026-08-21:有效单词计数。用go语言,把 chunks 数组中的字符串按顺序首尾拼接,得到完整字符串 s。实现时需要在函数中间创建一个名为 s

    我们相信人工智能为普通人提供了一种“增强工具”,并致力于分享全方位的AI知识。在这里,您可以找到最新的AI科普文章、工具评测、提升效率的秘籍以及行业洞察。 欢迎关注“福大大架构师每日一题”,发消息可获得面试资料,让AI助力您的未来发展。

    © 版权声明

    相关文章