【LeetCode】每日一题 -- 1170. 比较字符串最小字母出现频次 -- Java Version

news2025/6/22 0:36:00

题目链接:https://leetcode.cn/problems/compare-strings-by-frequency-of-the-smallest-character/

1. 题解(1170. 比较字符串最小字母出现频次)

昨天的每日一题 2699. 修改图中的边权 有点难,研究了一会儿,学习了一下 Dijkstra 算法,下午就无心学习,跑去玩了。

1.1 暴力解法:排序 + 二分

时间复杂度O((n+m)*p),空间复杂度O(n)

哔哔叨叨】:
很惭愧,从小就不喜欢读题,虽然做出来了,但是没按照题目要求来。该题首先让我们定义一个函数 f(s),用来统计一个字符串中(按字典序比较)最小字母的出现频次。这里我直接没管,自己想到哪写到哪了属于是 。
……
解题思路】:
那么下面我们就来看一下实现的思路:排序+二分;
题目给我们了两个数组 queries 以及 words,然后让我们返回一个数组 ans 。其中:

  • queries 需要我们与 words 进行对比查询,把得到的结果存入 ans
  • words是一个词汇表,需要我们提前将其中每个字符串的最小字母的出现频次计算好,并将结果也存入一个数组中保存;

……
分析到这题目已经十分明晰,我们具体要做的就是首先遍历一遍 words数组,得到其中所有的字符串的最小字母的出现频次,存入一个临时数组 tmp,然后对临时数组进行排序,方便我们后面统计words 中有多少比queries[i] 最小字母的出现频次高的字符串数量;之后,就是遍历words,对比比较,根据二分查找找出 tmp 数组中符合queries[i] 最小字母的出现频次的右边界,此时 右边界+1 一直到 tmp 数组结尾都是当前字符串频次大的数,所以我们可以直接通过数组长度减去右边界索引+1的方式得到ans[i]

class Solution {
    public int[] numSmallerByFrequency(String[] queries, String[] words) {
        /* 获取 queries 数组长度 */
        int n = queries.length;
        /* 定义答案数组 */
        int[] ans = new int[n];

        /* 定义 tmp 数组,用于临时存储 word 的最小字典序字母的数量 */
        int m = words.length;
        int[] tmp = new int[m];

        /* 统计 words 数组中所有 word 的最小字典序字母的数量 */
        for (String word : words) 
        {
            char[] ch = word.toCharArray();
            Arrays.sort(ch);
            int cnt = word.length() - word.replaceAll(String.valueOf(ch[0]),"").length();
            tmp[--m] = cnt;
        }

        /* 对 tmp 进行排序 */
        Arrays.sort(tmp);
        m = words.length;
        int i = 0;

        /* 遍历 queries 数组,计算答案 */
        for (String query : queries) 
        {
            char[] ch = query.toCharArray();
            Arrays.sort(ch);
            int cnt = query.length() - query.replaceAll(String.valueOf(ch[0]),"").length();
            int idx = bSearch(tmp, cnt, 0, m-1);
            ans[i++] = m - 1 == 0 ? m - idx : m - 1 - idx;
        }

        return ans;
    }

    /* 二分找右边界 */
    public int bSearch(int[] arr, int x, int l, int r) {
        while (l < r)
        {
            int mid = l + r + 1 >> 1;
            if (arr[mid] <= x) l = mid;
            else r = mid - 1;
        }
        return l;
    }
}

在这里插入图片描述

1.2 精简解法:后缀和 ⭐

时间复杂度O((n+m)*p),空间复杂度O(1)

哔哔叨叨】:
后缀和,顾名思义,就是前缀和反过来,例如,Sn = a[1]+a[2]+……+a[n]; 那么,后缀和就是 Sn = a[n], Sn-1 = a[n-1] + a[n], …… , S1 = a[1]+a[2]+……+a[n]; 在这里后缀和是为了方便我们加快答案的计算。
……
解题思路】:

  1. 根据题意,定义一个函数 f(s),用来统计一个字符串中(按字典序比较)最小字母的出现频次;
  2. 根据限定条件 1 <= queries[i].length, words[i].length <= 10,我们可以知道最小字母的出现频次最大不会超过10,因此我们可以直接定义一个数组 count 来记录 word 中最小字母的出现频次各有多少,然后倒序遍历,实现后缀和(方便计算,可以直接返回);
  3. 遍历 queries,让 res[i] 等于 count[当前字符串最小字母的出现频次+1](因为我们要找到的是比当前字符串最小字母的出现频次大的数量,所以要加1);
  4. 最后返回结果。
class Solution {
    public int[] numSmallerByFrequency(String[] queries, String[] words) {
        int[] count = new int[12];  // 限定条件
        for (String s : words) {
            count[f(s)]++;
        }
        /* 小于 count[i] 的数,也一定小于 count[i+1] */
        for (int i = 9; i >= 1; i--) {
            count[i] += count[i + 1];
        }
        /* 遍历 queries, 计算答案 */
        int[] res = new int[queries.length];
        for (int i = 0; i < queries.length; i++) {
            String s = queries[i];
            res[i] = count[f(s) + 1];
        }
        return res;
    }

    /* 返回一个字符串中最小字母的出现频次 */
    public int f(String s) {
        int cnt = 0;
        char ch = 'z';
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (c < ch) {
                ch = c;
                cnt = 1;
            } else if (c == ch) {
                cnt++;
            }
        }
        return cnt;
    }
}

在这里插入图片描述

2. 参考资料

[1] 比较字符串最小字母出现频次 – 官方题解
[2] Java 判断字符串中指定字符的个数

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

文件讲解—【C语言】

目录 1.为什么使用文件 2. 什么是文件 2.1 程序文件 2.2 数据文件 2.3 文件名 3. 文件的打开和关闭 3.1 文件指针 3.2 文件的打开和关闭 4. 文件的顺序读写 4.1 顺序读写函数介绍 4.2 对比一组函数 例子 例子 5.3 rewind 例子 6. 文本文件和二进制文件 测试代…

机器学习 day15(神经网络的工作原理,激活值a的公式)

1. 隐藏层的内部实现 如图通常来说&#xff0c;该模型一共有两层&#xff0c;不包括输入层&#xff08;layer 0&#xff09;&#xff0c;第一层是隐藏层&#xff08;layer 1&#xff09;&#xff0c;第二层是输出层&#xff08;layer 2&#xff09;&#xff0c;我们可以用方括…

【力扣刷题 | 第三天】242.有效字母异位词 349 两个数组的交集

目录 1.242. 有效的字母异位词 2.349. 两个数组的交集 - 力扣&#xff08;LeetCode&#xff09;​​​​​​ 使用算法笔记&#xff1a; 总结&#xff1a; 1.242. 有效的字母异位词 给定两个字符串 s 和 t &#xff0c;编写一个函数来判断 t 是否是 s 的字母异位词。 注意…

学习记录 -- Accurate and fast cell marker gene identification with COSG

文章目录 brief代码演示安装实操 个人感受 brief 单细胞数据分析当中&#xff0c;细胞聚类分群完成之后&#xff0c;我们希望得知每一个细胞类群是什么细胞&#xff0c;也就是细胞类型注释。 通常情况下&#xff0c;我们可以找到细胞类群间表达量存在差异的基因&#xff0c;我…

爆款视频生成器-视频批量剪辑系统源码开发分享

创建视频 该接口用于创建抖音视频&#xff08;支持话题, 小程序等功能&#xff09;。该接口适用于抖音。 使用限制 抖音的 OAuth API 以https://open.douyin.com/ 开头。挂载小程序请先完成注册开发者平台账号。创建抖音视频后, 会有一个审核过程, 期间只有自己可见。如果发…

【C/C++】带你快速掌握 使用—增强for(范围for循环)

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; &#x1f525;c系列专栏&#xff1a;C/C零基础到精通 &#x1f525; 给大…

Cefsharp-Winform114.2.100(5735)最新版本体验

版本说明: 官方仓库最新版本体验,114.2.100 (分支5735),支持MP3,WEBGL,不支持H264 视频体验H264参阅109版本(CSDN中搜索) Cefsharp109.1.110(winfrom)最新支持H264-MP3-MP4功能体验,导出pdf和下载方法有变调整_cef h264_久爱物联网的博客-CSDN博客 效果预览: 一…

LinuxC编程——高级文件操作

目录 一、查询文件信息1、stat2、stat fstat lstat区别 二、目录操作2.1 opendir2.2 readdir2.3 closedir例练习&#xff1a;实现ls操作 三、库3.1 库的定义3.2 库的分类3.2.1 静态库3.2.2 动态库 3.3 创建库3.3.1 静态库制作3.3.2 动态库制作 一、查询文件信息 1、stat int …

TLD7002学习笔记(二)-使用S32K144驱动TLD7002

文章目录 1. 前言2. 评估板简介3. 官方驱动3.1 官网驱动的介绍3.2 官方驱动的移植3.3 官方驱动的使用 4. 参考资料 1. 前言 本篇文章是TLD7002学习笔记的第二篇&#xff0c;主要是介绍如何使用S32K144驱动TLD7002-16ES。为此&#xff0c;笔者做了一套基于TLD7002-16ES的评估板…

重学Java的第一章

1.写在前面 今年的行情很差&#xff0c;差到很多人都没有办法找到工作&#xff0c;博主也是一个菜逼&#xff0c;找了一家小破公司&#xff0c;导致我那段时间很迷茫&#xff0c;也是也很焦虑&#xff0c;思考了很多&#xff0c;觉得我自己学的已经够多了&#xff0c;但是每一…

《Lua程序设计》--学习7

数据结构 数组 矩阵和多维数组 不规则数组&#xff1a;数组的数组&#xff0c;也就是所有元素均是另一个表的表 将两个索引合并为一个&#xff1a;声明一个长数组&#xff0c;然后根据 行数*行所拥有的元素个数列数来访问这样 链表 因为表是动态对象&#xff0c;所以在Lua语…

4.7 wait notify - 4.11 多把锁

目录 4.7 wait notify1、为什么需要wait2、原理之wait/notify3、API的介绍 4.8 wait notify 的正确姿势4.9 Park & Unpark4.10 重新理解线程状态转换4.11 多把锁 4.7 wait notify 1、为什么需要wait 当持有锁的线程因为某种条件不能满足不能执行时&#xff0c;由于其持有…

usb的传输类型

usb的传输类型 usb的四种传输类型: 批量传输同步传输(或等时传输)中断传输控制传输 其中的批量,同步,中断,三种传输中,每完整传输一次数据都称做一个事务(主要的数据传输是靠这三种传输) 事务的具体表现(批量,同步,中断) ​ 上图说说的输入事务是以主机来说的, 主机需要先发…

EMC学习笔记(三)滤波

滤波 1.概述2.滤波器件2.1 电阻2.2 电感2.3 电容2.4 铁氧体磁珠2.5 共模电感 3.滤波电路3.1 滤波电路的形式3.2 滤波电路的布局与布线 4.电容在PCB的EMC设计中的应用4.1 滤波电容的种类4.2 电容自谐振问题4.3 ESR对并联电容幅频特性的影响4.4 ESL对并联电容幅频特性的影响4.5 电…

JVM原理:JVM运行时内存模型(通俗易懂)

目录 前言正文虚拟机栈局部变量表操作数栈动态链接方法返回地址 本地方法栈本地方法存在的意义本地方法的调用 虚拟机堆堆结构Eden区Survivor区域老年代Old区常用参数指令 方法区常量池 运行时常量池方法信息类信息域信息JDK1.7前的方法区JDK1.7时的方法区JDK1.7后的方法区 程序…

Spring-2

DI 依赖注入 所谓依赖注入&#xff0c;是指程序运行过程中&#xff0c;如果需要调用另一个对象协助时&#xff0c;无须在代码中创建被调用者&#xff0c;而是依赖于外部的注入<bean id”” class”” p:属性名称-ref”另外受管 bean 的名称”/> IoC 实际上有 2 种实现 …

探索Python工具库合集:提高开发效率的秘密武器

前言&#x1f680;&#x1f680; 在开发过程中&#xff0c;笔者积累了许多实用的Python工具函数和模块&#xff0c;决定将它们整理成一个工具库集合&#xff0c;并与大家分享。本文将介绍笔者的Python工具库集合的核心功能和用途&#xff0c; 在日常的Python开发中&#xff0c;…

Selenium Python教程第6章:使用页面对象

6. Page Objects 页面对象 6.1 什么是页面对象模型(POM)&#xff1f; 页面对象模型(Page Objects Model, POM )是一组旨在表示一个或多个网页的类, 用1个类来保存1个网页上所有的元素&#xff0c;相似的网页可以重用此类。 1个网站通常有多个页面&#xff0c;可以用多个页面类…

(opencv)图像几何变换——缩放

图像缩放是指将图像的尺寸变小或变大的过程&#xff0c;也就是减少或增加源图像数据的像素个数。图像缩放一定程度上会造成信息的丢失&#xff0c;因此需要考虑适宜的方法进行操作。 下面介绍两种常用的图像缩放方法的原理及实现 1.基于等间隔提取图像缩放 等间隔提取图像缩…

多线程目录

基础概念篇 001线程状态图示_存在,及合理的博客-CSDN博客例如&#xff1a;随着人工智能的不断发展&#xff0c;机器学习这门技术也越来越重要&#xff0c;很多人都开启了学习机器学习&#xff0c;本文就介绍了机器学习的基础内容。提示&#xff1a;以下是本篇文章正文内容&…