LeetCode1170 比较字符串最小字母出现频次

字符串算法探秘:最小字母频次统计与比较问题剖析

在编程的世界里,字符串处理问题犹如繁星般繁多且各具特色。今天,我们聚焦于一道饶有趣味的题目,它涉及到对字符串中最小字母出现频次的统计以及基于此的比较操作。这道题不仅考验我们对字符串基本操作的掌握程度,还能锻炼我们的算法思维和问题解决能力。

一、题目详述

1. 核心函数定义

首先,我们需要定义一个函数 f(s) ,它的任务是统计字符串 s 中按字典序比较最小字母的出现频次。这里的字典序就是我们平常所说的字母顺序,比如在英文字母表中,a 排在 b 前面,b 又排在 c 前面 。例如,对于字符串 s = "dcce" ,我们先找到字典序最小的字母是 "c" ,然后统计它在字符串中出现的次数,发现出现了 2 次,所以 f(s) = 2 。

2. 数组比较任务

接着,题目给定了两个字符串数组,分别是待查表 queries 和词汇表 words 。我们的目标是对于 queries 数组中的每一个查询字符串 queries[i] ,统计 words 数组中满足 f(queries[i]) < f(W) 的词的数目,这里的 W 代表 words 数组中的每一个词。最后,要将每次查询的结果存储在一个整数数组 answer 中返回,其中 answer[i] 就是第 i 次查询的结果。

二、解题思路探索

1. 拆解 f 函数的实现

  • 寻找最小字母:要实现 f 函数,我们首先要遍历字符串 s ,找到其中字典序最小的字母。可以通过一个简单的循环,从字符串的第一个字符开始,依次与后面的字符进行比较。如果遇到比当前最小字母还要小的字符,就更新最小字母。

  • 统计最小字母频次:在找到最小字母后,再次遍历字符串 s ,统计这个最小字母出现的次数。通过这样两次遍历,就能准确计算出 f(s) 的值。

2. 整体流程规划

  • 计算 queries 数组中每个字符串的 f 值:对于 queries 数组中的每一个字符串,调用 f 函数计算其最小字母的出现频次。

  • 计算 words 数组中每个字符串的 f 值:同样,对 words 数组中的每一个字符串,也调用 f 函数计算其最小字母的出现频次。

  • 比较与计数:对于 queries 数组中的每一个元素,遍历 words 数组,将 queries 元素的 f 值与 words 元素的 f 值进行比较。如果 queries 元素的 f 值小于 words 元素的 f 值,就将计数器加 1 。最后,将这个计数器的值存入 answer 数组中对应的位置。

三、代码实现展示(C 语言)

1. 实现 f 函数

// 计算字符串中字典序最小字母的出现频次
int f(char *s) {
    char minChar = s[0];
    for (int i = 1; i < strlen(s); i++) {
        if (s[i] < minChar) {
            minChar = s[i];
        }
    }
    int count = 0;
    for (int i = 0; i < strlen(s); i++) {
        if (s[i] == minChar) {
            count++;
        }
    }
    return count;
}

2. 主函数实现

// 统计满足条件的词汇表中词的数目
int* numSmallerByFrequency(char** queries, int queriesSize, char** words, int wordsSize, int* returnSize) {
    int* answer = (int*)malloc(queriesSize * sizeof(int));
    if (answer == NULL) {
        return NULL;
    }
    for (int i = 0; i < queriesSize; i++) {
        int queryFreq = f(queries[i]);
        int smallerCount = 0;
        for (int j = 0; j < wordsSize; j++) {
            int wordFreq = f(words[j]);
            if (queryFreq < wordFreq) {
                smallerCount++;
            }
        }
        answer[i] = smallerCount;
    }
    *returnSize = queriesSize;
    return answer;
}

3. 代码解释

  • f 函数:在 f 函数中,首先定义一个变量 minChar 并初始化为字符串 s 的第一个字符。然后通过一个 for 循环遍历字符串 s ,从第二个字符开始,每次比较当前字符与 minChar ,如果当前字符更小,就更新 minChar 。这样遍历完后,minChar 就是字符串中字典序最小的字母。接着,再通过另一个 for 循环遍历字符串 s ,统计 minChar 出现的次数,最后返回这个次数。

  • numSmallerByFrequency 函数:在这个主函数中,首先为 answer 数组分配内存空间,用于存储最终的查询结果。然后通过两层循环来实现查询和比较。外层循环遍历 queries 数组,对于每一个 queries[i] ,调用 f 函数计算其最小字母出现频次 queryFreq 。内层循环遍历 words 数组,对于每一个 words[j] ,调用 f 函数计算其最小字母出现频次 wordFreq 。如果 queryFreq 小于 wordFreq ,就将 smallerCount 加 1 。内层循环结束后,将 smallerCount 的值存入 answer[i] 。最后,设置 returnSize 为 queriesSize ,并返回 answer 数组。

四、复杂度分析

1. 时间复杂度

  • f 函数f 函数需要遍历字符串两次,每次遍历的时间复杂度与字符串的长度成正比。假设字符串长度为 n ,那么 f 函数的时间复杂度为O(n)

  • 整体算法:对于 queries 数组中的每一个字符串(假设有 q 个),都要调用 f 函数,然后对于每一个 queries 中的字符串,又要遍历 words 数组(假设有 w 个)中的每一个字符串并调用 f 函数。所以整体的时间复杂度为 O(q\times n+q\times w\times n ) ,简化后为O(qn+qwn),其中 n 是字符串的平均长度。如果 qw 和 n 都比较大,时间复杂度会比较高,在处理大规模数据时可能会出现性能问题。

2. 空间复杂度

  • 算法中主要的空间开销是用于存储结果的 answer 数组。answer 数组的长度与 queries 数组的长度相同,假设 queries 数组的长度为 q ,那么空间复杂度为O(q)。除此之外,算法中使用的临时变量如 minCharcountqueryFreqsmallerCountwordFreq 等,它们所占用的空间都是常数级别的,不会随着输入规模的增大而增加。所以,总的空间复杂度为O(q) 。

五、总结与拓展

通过解决这道字符串最小字母频次统计与比较的问题,我们深入学习了字符串的遍历、字符比较以及数组的操作。在实际编程中,类似的字符串处理场景非常常见,比如文本分析、数据清洗等。掌握这类问题的解法,能够为我们解决更复杂的实际问题奠定坚实的基础。

对于这道题,我们还可以进一步思考优化的方向。例如,在计算 f 值时,由于每个字符串的 f 值是固定的,我们可以在第一次计算后将其存储起来,避免重复计算,从而提高算法的效率。另外,在比较 queries 和 words 数组的 f 值时,也可以考虑使用更高效的数据结构或算法,比如排序后使用二分查找,这样可以将时间复杂度从 O(qwn)降低到O(qw\log w),大大提升算法在大规模数据下的性能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/953189.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Kafka 分区管理

分区是主题的子集&#xff0c;每个主题可以被分割成多个分区&#xff0c;一个分区有一个主副本&#xff08;Leader&#xff09;及一个或多个从&#xff08;Follower&#xff09;副本。分区允许将数据分布在多个broker上&#xff0c;这样可以提高数据的处理能力、并行性及可靠性…

xcrun: error: invalid active developer path 解决

在拉取 github 代码时&#xff0c;提示如下报错&#xff1a; xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun 原因是&#xff1a;这是由于 Xcode command line t…

2025华数杯国际赛A题完整论文讲解(含每一问python代码+数据+可视化图)

大家好呀&#xff0c;从发布赛题一直到现在&#xff0c;总算完成了2025“华数杯”国际大学生数学建模竞赛A题Can He Swim Faster的完整的成品论文。 本论文可以保证原创&#xff0c;保证高质量。绝不是随便引用一大堆模型和代码复制粘贴进来完全没有应用糊弄人的垃圾半成品论文…

Python 二次元初音未来桌宠

标题 相关资源文件已经打包成EXE文件&#xff0c;可双击直接运行程序&#xff0c;且文章末尾已附上相关源码&#xff0c;以供大家学习交流&#xff0c;博主主页还有更多Python相关程序案例&#xff0c;秉着开源精神的想法&#xff0c;望大家喜欢&#xff0c;点个关注不迷路&…

vue3学习日记5 - 项目起步

最近发现职场前端用的框架大多为vue&#xff0c;所以最近也跟着黑马程序员vue3的课程进行学习&#xff0c;以下是我的学习记录 视频网址&#xff1a; Day2-11.项目起步-静态资源引入和ErrorLen安装_哔哩哔哩_bilibili 学习日记&#xff1a; vue3学习日记1 - 环境搭建-CSDN博…

【Linux系统】—— vim 的使用

【Linux系统】—— vim 的使用 1 vim 的基本概念2 vim 的多模式3 命令模式下的命令集3.1 进入/退出其他模式3.2 光标移动命令集3.3 复制/剪切/粘贴/删除命令集3.4 撤销命令集3.5 查找命令集3.6 替换命令集3.7 进入与退出替换模式 4 批量化编译5 底行模式6 vim 小技巧7 vim简单配…

JAVA实战开源项目:课程智能组卷系统(Vue+SpringBoot) 附源码

本文项目编号 T 009 &#xff0c;文末自助获取源码 \color{red}{T009&#xff0c;文末自助获取源码} T009&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析 六、核心代码6.1 老…

了解 Ansys Mechanical 中的网格方法:综合指南

网格是每个有限元分析 &#xff08;FEA&#xff09; 仿真的支柱。它将几何图形划分为离散单元&#xff0c;使 Ansys Mechanical 能够近似模型在各种条件下的行为。结构良好的网格可确保准确、可靠和计算高效的结果&#xff0c;而结构不佳的网格可能会导致错误、收敛问题或不必要…

【Linux】深刻理解软硬链接

一.软硬链接操作 1.软连接 touch 创建一个文件file.txt &#xff0c;对该文件创建对应的软链接改怎么做呢&#xff1f; ln -s file.txt file-soft.link .给对应文件创建软连接。 软连接本质就是一个独立的文件&#xff0c;因为我们对应的软连接有独立的inode&#xff0c;他…

施耐德M241与MR30-FBS-MT 在Machine Expert V2.0的组态过程

一、系统概述 MR30分布式IO是一个高度灵活的可扩展分布式 I/O 系统&#xff0c;MR30-FBC-MT用于通过 Modbus TCP 总线将过程信号连接到上一级控制器。 具有以下特点&#xff1a; 结构紧凑 PUSH IN端子&#xff0c;易于安装&#xff0c;布线简单 灵活性高&#xff1a;开关量模…

大数据技术在服饰行业的应用

大数据技术的快速发展为各行各业带来了深刻的变革&#xff0c;本文将详细探讨大数据技术的发展脉络&#xff0c;大数据技术推动服饰企业的数字化转型&#xff0c;旨在为相关领域的研究和实践提供参考。 什么是大数据大数据技术的发展历程大数据在服饰行业的应用总结 1&#xff…

Vue2+OpenLayers添加/删除点、点击事件功能实现(提供Gitee源码)

目录 一、案例截图 二、安装OpenLayers库 三、安装Element-UI 四、代码实现 4.1、添加一个点 4.2、删除所有点 4.3、根据经纬度删除点 4.4、给点添加点击事件 4.5、完整代码 五、Gitee源码 一、案例截图 可以新增/删除标记点&#xff0c;点击标记点可以获取到当前标…

Windows 10 ARM工控主板连接I2S音频芯片

在Windows工控主板应用中&#xff0c;音频功能是一项基本的需求&#xff0c;USB声卡在x86/x64 Windows系统上就可直接免驱使用&#xff0c;但这些USB声卡通常不提供ARM上的Windows系统驱动。本文将介绍如何利用安装在ARM上的Windows工控主板——ESM8400的I2S接口、连接WM8960音…

【Rust】错误处理机制

目录 思维导图 引言 一、错误处理的重要性 1.1 软件中的错误普遍存在 1.2 编译时错误处理要求 二、错误的分类 2.1 可恢复错误&#xff08;Recoverable Errors&#xff09; 2.2 不可恢复错误&#xff08;Unrecoverable Errors&#xff09; 三、Rust 的错误处理机制 3…

提升租赁效率的租赁小程序全解析

内容概要 在如今快节奏的生活中&#xff0c;租赁小程序俨然成为了提升租赁效率的一把利器。无论是个人还是企业&#xff0c;都会因其便捷的功能而受益。简单来说&#xff0c;租赁小程序能让繁琐的租赁流程变得轻松、高效。在这里&#xff0c;我们将带您畅游租赁小程序的海洋&a…

SSM商城设计与实现

摘 要 本文的主要工作是对基于B/S模式及JSP技术的基于智能推荐的b2c销售网站进行了研究与设计。本文首先介绍了基于智能推荐的b2c销售网站的背景&#xff0c;分析比较了国内外相关基于智能推荐的b2c销售网站的运行模式、系统特点与开发技术。然后分析了目前热点的各种Web应用开…

drawDB docker部属

docker pull xinsodev/drawdb docker run --name some-drawdb -p 3000:80 -d xinsodev/drawdb浏览器访问&#xff1a;http://192.168.31.135:3000/

CentOS7下Hadoop集群分布式安装详细图文教程

1、集群规划 主机 角色 DSS20 NameNode DataNode ResourceManager NodeManager DSS21 SecondaryNameNode NameNode NodeManager DSS22 DataNode NodeManager 1.1、环境准备 1.1.1 关闭防火墙 #查看防火墙状态 firewall-cmd --state #停止…

计算机网络——网络层-IPV4相关技术

一、网络地址转换NAT • 网络地址转换 NAT 方法于1994年提出。 • 需要在专用网连接到因特网的路由器上安装 NAT 软件。装有 NAT 软件的路由器叫做 NAT路由器&#xff0c;它至少有一个有效的外部全球地址 IPG。 • 所有使用本地地址的主机在和外界通信时都要在 NAT 路由器上将…

postgresql|数据库|利用sqlparse和psycopg2库批量按顺序执行SQL语句(psyconpg2新优化版本)

一、 旧版批量执行SQL脚本的python文件缺点&#xff0c;优点&#xff0c;以及更新内容 书接上回&#xff0c;postgresql|数据库开发|python的psycopg2库按指定顺序批量执行SQL文件(可离线化部署)_python sql psycopg2-CSDN博客 这个python脚本写了很久了&#xff0c;最近开始…