news 2026/4/30 12:31:43

字符串计数匹配 (Python JAVA C++ JS C)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
字符串计数匹配 (Python JAVA C++ JS C)

题目描述

给你一个字符串str和整数k,返回满足以下条件的所有子字符串个数:

  1. 恰好包含k个字母。
  2. 数字0-9各出现至少一次。

输入描述

  • 第一行字符串str(1≤ length ≤ 100000),仅包含数字和小写字母
  • 第二行为整数k(0 ≤ k ≤100000 )

输出描述

输出一个整数,表示满足所有条件的子字符串的个数。

子字符串是字符串中连续的非空字符序列

示例1

输入

a0123456789aa 1

输出

2

问题分析

题目要求统计满足以下条件的子字符串个数:

  1. 子字符串恰好包含k个字母(大小写不敏感,题目中均为小写字母)。
  2. 子字符串中数字0-9各出现至少一次。

解决思路

  1. 滑动窗口:使用滑动窗口技术高效遍历所有可能的子字符串。
  2. 字母计数:维护窗口内字母的数量,确保恰好为k
  3. 数字覆盖:确保窗口内包含所有数字0-9至少一次。
  4. 优化检查:在满足字母数量时检查数字覆盖情况。

算法步骤

  • 初始化左右指针leftright,表示窗口的左右边界。
  • 维护两个哈希表或数组:letterCount统计字母数量,digitCount统计数字出现情况。
  • 移动右指针扩展窗口,更新计数。
  • 当字母数量等于k时,检查数字是否覆盖0-9
  • 移动左指针收缩窗口,确保字母数量不超过k

代码实现

C++ 实现
#include <iostream> #include <string> #include <unordered_map> using namespace std; int countSubstrings(const string &str, int k) { int n = str.size(); int res = 0; int left = 0; unordered_map<char, int> letterCount; unordered_map<char, int> digitCount; int requiredDigits = 10; for (int right = 0; right < n; ++right) { char c = str[right]; if (isdigit(c)) { digitCount[c]++; } else { letterCount[c]++; } while (letterCount.size() > k || (letterCount.size() == k && digitCount.size() < requiredDigits)) { char leftChar = str[left]; if (isdigit(leftChar)) { digitCount[leftChar]--; if (digitCount[leftChar] == 0) { digitCount.erase(leftChar); } } else { letterCount[leftChar]--; if (letterCount[leftChar] == 0) { letterCount.erase(leftChar); } } left++; } if (letterCount.size() == k && digitCount.size() == requiredDigits) { res++; } } return res; } int main() { string str; int k; cin >> str >> k; cout << countSubstrings(str, k) << endl; return 0; }
Python 实现
def count_substrings(s, k): n = len(s) res = 0 left = 0 letter_count = {} digit_count = {} required_digits = 10 for right in range(n): c = s[right] if c.isdigit(): digit_count[c] = digit_count.get(c, 0) + 1 else: letter_count[c] = letter_count.get(c, 0) + 1 while len(letter_count) > k or (len(letter_count) == k and len(digit_count) < required_digits): left_char = s[left] if left_char.isdigit(): digit_count[left_char] -= 1 if digit_count[left_char] == 0: digit_count.pop(left_char) else: letter_count[left_char] -= 1 if letter_count[left_char] == 0: letter_count.pop(left_char) left += 1 if len(letter_count) == k and len(digit_count) == required_digits: res += 1 return res s = input().strip() k = int(input()) print(count_substrings(s, k))
Java 实现
import java.util.HashMap; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); String str = scanner.nextLine(); int k = scanner.nextInt(); System.out.println(countSubstrings(str, k)); } public static int countSubstrings(String str, int k) { int n = str.length(); int res = 0; int left = 0; HashMap<Character, Integer> letterCount = new HashMap<>(); HashMap<Character, Integer> digitCount = new HashMap<>(); int requiredDigits = 10; for (int right = 0; right < n; right++) { char c = str.charAt(right); if (Character.isDigit(c)) { digitCount.put(c, digitCount.getOrDefault(c, 0) + 1); } else { letterCount.put(c, letterCount.getOrDefault(c, 0) + 1); } while (letterCount.size() > k || (letterCount.size() == k && digitCount.size() < requiredDigits)) { char leftChar = str.charAt(left); if (Character.isDigit(leftChar)) { digitCount.put(leftChar, digitCount.get(leftChar) - 1); if (digitCount.get(leftChar) == 0) { digitCount.remove(leftChar); } } else { letterCount.put(leftChar, letterCount.get(leftChar) - 1); if (letterCount.get(leftChar) == 0) { letterCount.remove(leftChar); } } left++; } if (letterCount.size() == k && digitCount.size() == requiredDigits) { res++; } } return res; } }
JavaScript 实现
function countSubstrings(str, k) { let n = str.length; let res = 0; let left = 0; let letterCount = new Map(); let digitCount = new Map(); const requiredDigits = 10; for (let right = 0; right < n; right++) { const c = str[right]; if (/\d/.test(c)) { digitCount.set(c, (digitCount.get(c) || 0) + 1); } else { letterCount.set(c, (letterCount.get(c) || 0) + 1); } while (letterCount.size > k || (letterCount.size === k && digitCount.size < requiredDigits)) { const leftChar = str[left]; if (/\d/.test(leftChar)) { digitCount.set(leftChar, digitCount.get(leftChar) - 1); if (digitCount.get(leftChar) === 0) { digitCount.delete(leftChar); } } else { letterCount.set(leftChar, letterCount.get(leftChar) - 1); if (letterCount.get(leftChar) === 0) { letterCount.delete(leftChar); } } left++; } if (letterCount.size === k && digitCount.size === requiredDigits) { res++; } } return res; } const readline = require('readline'); const rl = readline.createInterface({ input: process.stdin, output: process.stdout }); let input = []; rl.on('line', (line) => { input.push(line); if (input.length === 2) { const str = input[0]; const k = parseInt(input[1]); console.log(countSubstrings(str, k)); rl.close(); } });
C 实现
#include <stdio.h> #include <string.h> #include <ctype.h> #define MAX_CHAR 128 int countSubstrings(const char *str, int k) { int n = strlen(str); int res = 0; int left = 0; int letterCount[MAX_CHAR] = {0}; int digitCount[MAX_CHAR] = {0}; int uniqueLetters = 0; int uniqueDigits = 0; int requiredDigits = 10; for (int right = 0; right < n; ++right) { char c = str[right]; if (isdigit(c)) { if (digitCount[c] == 0) { uniqueDigits++; } digitCount[c]++; } else { if (letterCount[c] == 0) { uniqueLetters++; } letterCount[c]++; } while (uniqueLetters > k || (uniqueLetters == k && uniqueDigits < requiredDigits)) { char leftChar = str[left]; if (isdigit(leftChar)) { digitCount[leftChar]--; if (digitCount[leftChar] == 0) { uniqueDigits--; } } else { letterCount[leftChar]--; if (letterCount[leftChar] == 0) { uniqueLetters--; } } left++; } if (uniqueLetters == k && uniqueDigits == requiredDigits) { res++; } } return res; } int main() { char str[100001]; int k; scanf("%s %d", str, &k); printf("%d\n", countSubstrings(str, k)); return 0; }

代码说明

  • 滑动窗口:通过左右指针动态调整窗口大小。
  • 哈希表/数组:用于统计字母和数字的出现次数。
  • 条件检查:确保字母数量为k且数字覆盖0-9
  • 时间复杂度:O(n),每个字符最多被访问两次(左右指针各一次)。
  • 空间复杂度:O(1),使用固定大小的数组或哈希表。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/30 18:10:38

机试真题——识文断句(2025B卷:200分)Java/python/JavaScript/C++/C最佳实现

给定一些短词字符串作为分割词&#xff0c;去分割一段长字符串。从前往后遍历分割词&#xff0c;查找并分割长字符串为对应的token。分词规则如下: 1.优先匹配最长分割词:若多个分割词可匹配同一位置&#xff0c;选择长度最长的;长度相同时&#xff0c;按字典序较大的优先。 2.…

作者头像 李华
网站建设 2026/4/20 22:14:56

音乐小说内容重复识别(Java JS Python C++C)

题目描述实现一个简易的重复内容识别系统&#xff0c;通过给定的两个内容名称&#xff0c;和相似内容符号&#xff0c;判断两个内容是否相似&#xff1b;如果相似&#xff0c;返回相似内容&#xff1b;如果不相似&#xff0c;返回不相似的内容。初始化&#xff1a;给出两个字符…

作者头像 李华
网站建设 2026/4/28 15:37:37

银月光紫外LED光源 | G3535N1UVN2U12-302nm | 高均匀度透射仪专用

在分子生物学及相关科研领域&#xff0c;紫外透射仪作为观察与分析核酸电泳条带的关键工具&#xff0c;其光源的性能直接影响成像清晰度、操作便捷性及长期使用成本。传统302nm紫外灯管虽沿用多年&#xff0c;但其普遍存在寿命有限、体积庞大、光衰较快、能效较低等问题。为应对…

作者头像 李华
网站建设 2026/5/1 6:08:29

等级保护建设方案,等保2.0,等保3.0解决方案PPT文件和WORD文件

等保资料合集&#xff1a;等保2.0网络安全等级保护解决方案等保2.0政策规范解读&#xff08;63页PPT&#xff09;等保三级技术建议书等保三级建设方案&#xff08;69页Word&#xff09;等级保护新标准(2.0)介绍密码应用安全性评估方案三级等保安全解决方案商用密码应用安全性评…

作者头像 李华
网站建设 2026/4/23 16:40:03

OpenAI开源GPT-OSS-120b/20b:单卡可运行的MoE推理模型

OpenAI开源GPT-OSS-120b/20b&#xff1a;单卡可运行的MoE推理模型 在消费级GPU上跑一个接近GPT-4能力的语言模型&#xff0c;曾经是开发者社区遥不可及的梦想。而现在&#xff0c;OpenAI用两款名为 gpt-oss-120b 和 gpt-oss-20b 的新模型&#xff0c;把这扇门推开了。 更令人意…

作者头像 李华
网站建设 2026/5/1 2:22:22

Qwen3-32B模型幻觉问题初探

Qwen3-32B的幻觉问题&#xff0c;真不能忽视 试了下Qwen3-32B&#xff0c;第一反应是&#xff1a;这模型太强了。 响应快、逻辑顺、写代码像资深工程师&#xff0c;回答专业问题也一套一套的。你几乎要以为它真“懂”了——理解语义、掌握知识、会推理&#xff0c;甚至能帮你设…

作者头像 李华