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. 1. 初始化一个空哈希表cnt,用于记录每个单词出现的次数。

  2. 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)
}
打开网易新闻 查看精彩图片

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))
打开网易新闻 查看精彩图片

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;
}
打开网易新闻 查看精彩图片

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