首页 > 编程语言 >java数据结构与算法刷题-----LeetCode451. 根据字符出现频率排序

java数据结构与算法刷题-----LeetCode451. 根据字符出现频率排序

时间:2024-03-24 12:00:35浏览次数:20  
标签:字符 java LeetCode451 int 复杂度 次数 ----- hash 排序

java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完):https://blog.csdn.net/grd_java/article/details/123063846

文章目录

在这里插入图片描述

1. hash统计出现次数后排序

解题思路:时间复杂度O( ) ,空间复杂度 O ( ),空间复杂度O( ),空间复杂度O()
  1. 通过hash表统计每个字符的出现次数,时间复杂度O( n n n)
  2. 对hash表按照出现次数降序排序,时间复杂度O( k ∗ l o g 2 k k*log_2{k} k∗log2​k)是快速排序的时间复杂度。其中k是hash大小,也就是字符串中不重复的字母个数

如果使用数组作为hash表,不使用HashMap的话,则不需要排序

  1. 然后依次将最大出现次数的字符,拼接起来,输出。正好是按照排序好的hash表进行输出。O( k k k)

使用数组作为hash表,虽然不需要排序,但是每次都得遍历整个hash表找到出现次数最多的字符。因此时间复杂度O( n ∗ k n*k n∗k)其中n是字符串大小,k是hash表大小。我们需要找到n个字符拼接为结果字符串,每次都需要完整遍历hash表(长度为k)找到出现次数最多的

  1. 因此时间复杂度为
  1. 直接使用HashMap,时间复杂度O( n + k ∗ l o g 2 k n+k*log_2{k} n+k∗log2​k),空间复杂度O( n + k n+k n+k).另外快速排序也需要额外栈空间O( l o g 2 k log_2{k} log2​k)
  2. 使用数组作为hash表,时间复杂度O( n + n ∗ k n+n*k n+n∗k),空间复杂度O(n+k).

使用数组作为hash表所需大小:
字符串包含大小写字母和数字,ASCII码如下:A = 65,Z = 90. a = 97,z = 122,0 = 48,9 = 57
因此hash表大小为123即可(下标从0到122)。并且从48开始,前面47的下标是没有用的

代码:选用数组作为hash,因为这样更难,做题情况下,比使用HashMap效率高很多(工作场景下没什么区别)。但是工作场景中,要使用HashMap。

在这里插入图片描述

class Solution {
    public String frequencySort(String s) {
        int[] list = new int[123];//hash表
        char[] chars = s.toCharArray();//获取字符数组
        for (int i = 0; i < chars.length; i++) {//统计每个字符出现的次数
            int n = (int) chars[i];//获取当前字符的ASCII码
            list[n]++;//对应hash位置+1
        }
        int index = 0;//结果字符数组的下标
        while (index < chars.length) {
            int max = 0;//保存最大值
            char target = ' ';//保存出现次数最多的字符
            for (int i = 48; i < list.length; i++) {//遍历hash表
                if (list[i] > max) {//如果当前字符出现次数更多
                    max = list[i];//保存这个次数
                    target = (char) i ;//让target指向这个字符
                }
            }
            for (int j = 0; j < max; j++) {//将其拼接到字符数组中
                chars[index++] = target;
            }
            list[target] = 0;//hash表中已经输出的字符归0
        }
        return String.valueOf(chars);
    }
}

2. 桶排序

解题思路:时间复杂度O( n + k n+k n+k),空间复杂度O( n + k n+k n+k)
  1. 先通过hash表统计每个字符的出现次数,时间复杂度O( n n n)
  2. 然后按照出现次数,将字符放入对应桶中。时间复杂度O( k k k)

桶保存的是对应出现次数的字符。例如1号桶保存出现1次的字符,2号桶保存出现次数为2的字符

  1. 然后从后往前遍历桶(出现次数高的先拼接到字符串)。时间复杂度O( k k k)

记住,当前是几号桶,取出的字符就出现几次。因此我们拼接字符串时,要将取出的字符每个都拼接对应桶的次数

代码:因为使用了StringBuilder,做题场景下的效率反而比方法1慢,但是实际工作场景中,肯定是这个方法的时间复杂度更优

在这里插入图片描述

class Solution {
   public String frequencySort(String s) {
        char[] charArray = s.toCharArray();
        int[] freq = new int[128]; // 使用128大小的数组,考虑到ASCII码表
        StringBuilder[] buckets = new StringBuilder[s.length() + 1];//桶,个数为字符串中字符个数+1
        // 统计字符出现频率
        for (char c : charArray) freq[c]++;
        // 将字符按照频率放入对应的桶中,出现次数是几,就放入几号桶
        for (int i = 48; i < 128; i++) {
            if (freq[i] > 0) {//如果当前字符出现次数>0
                //放入对应出现次数的桶中,例如当前字符出现3次,就放入3号桶
                if (buckets[freq[i]] == null) buckets[freq[i]] = new StringBuilder();//如果当前桶为空,先创建桶
                buckets[freq[i]].append((char)i);//然后将字符添加到桶中
            }
        }
        // 构建结果字符串
        StringBuilder result = new StringBuilder();
        for (int i = buckets.length-1; i > 0; i--) {//从后往前遍历桶
            if (buckets[i] != null) {//先查看,统计出现次数最高字符的桶
                for (char c : buckets[i].toString().toCharArray()) {//依次取出桶中字符
                    for (int j = 0; j < i; j++) {//当前是i号桶,这个字符需要添加i次,因为i是它的出现次数
                        result.append(c);
                    }
                }
            }
        }
        return result.toString();
    }
}

标签:字符,java,LeetCode451,int,复杂度,次数,-----,hash,排序
From: https://blog.csdn.net/grd_java/article/details/136983196

相关文章

  • nginx挂载配置文件和日志-静态目录-方式二
    环境说明linux系统版本:lsb_release-a docker版本:docker-v Nginx镜像版本:1.24.0 不同的操作系统以及软件版本,可能会遇到不一样的问题,一定要注意版本问题。 .1.创建需要挂载的文件目录,比如html和log,还有配置文件nginx.conf.自己首先创建一个目录,结构如下。 ......
  • 数据分析-Pandas分类数据的类别处理
    数据分析-Pandas分类数据的类别处理数据分析和处理中,难免会遇到各种数据,那么数据呈现怎样的规律呢?不管金融数据,风控数据,营销数据等等,莫不如此。如何通过图示展示数据的规律?数据表,时间序列数据在数据分析建模中很常见,例如天气预报,空气状态监测,股票交易等金融场景。数据分析......
  • 【CSP试题回顾】202303-2-垦田计划(优化)
    CSP-202303-2-垦田计划关键点:二分查找在这个问题中,有一系列的田地需要在特定的时间tit_iti......
  • flutter3-dylive仿抖音App实例|Flutter3+Getx实战短视频直播应用
    原创研发flutter3+getX+mediaKit跨平台仿抖音app短视频直播实战Flutter3-DouYin。flutter3_dylive使用最新跨平台技术flutter3.x+dart3+getx+get_storage+media_kit开发手机端仿抖音app小视频直播实战项目。实现了抖音全屏式上下滑动视频、左右滑动切换页面模块,直播间进场/礼物动......
  • 2023 dl实战精选-基于Keras的深度神经网络应用实战
    本书介绍    深度学习是一组令人兴奋的神经网络新技术。通过高级的训练技术和神经网络架构组件的组合就可以创建能够处理表格数据、图像、文本和音频作为输入和输出的神经网络。深度学习允许神经网络以类似于人脑功能的方式学习信息的层次结构。免费获取:2023dl实战精......
  • 刚刚!奥特曼剧透GPT-5,将在高级推理功能上实现重大进步
    奥特曼:“GPT-5的能力提升幅度将超乎人们的想象…”自Claude3发布以来,外界对GPT-5的期待越来越强。毕竟Claude3已经全面超越了GPT-4,成为迄今为止最强大模型。而且距离GPT-4发布已经过去了整整一年时间,2023年3月14日OpenAI官宣发布GPT-4。关于GPT-4.5或GPT-5......
  • C#9.0新特性详解系列之四:顶级程序语句(Top-Level Programs)
    原文链接:https://www.cnblogs.com/markkang/p/14091908.html1背景与动机通常,如果只想用C#在控制台上打印一行“HelloWorld!”,这可不是Console.WriteLine("HelloWorld!");一条语句就可以搞定的,还涉及到其他必要基础代码(如定义类和入口函数Main),例如下面:usingSystem;classProgr......
  • 3.MySQL数据库的基本操作-DQL 基本操作
    MySQL数据库的基本操作-DQL基本操作查询select语法格式select[all|distinct]<目标列的表达式1>[别名],<目标列的表达式2>[别名]...from<表名或视图名>[别名],<表名或视图名>[别名]...[where<条件表达式>][groupby<列名>[having<条件表达式>]][o......
  • 基于java中的springboot实现校园周边美食探索及分享平台演示【附项目源码+论文说明】
    基于springboot实现校园周边美食探索及分享平台演示摘要美食一直是与人们日常生活息息相关的产业。传统的电话订餐或者到店消费已经不能适应市场发展的需求。随着网络的迅速崛起,互联网日益成为提供信息的最佳俱渠道和逐步走向传统的流通领域,传统的美食业进而也面临着巨大......
  • 基于java中的springboot实现蜗牛兼职网的设计与实现演示【附项目源码+论文说明】
    基于springboot实现蜗牛兼职网的设计与实现演示摘要随着科学技术的飞速发展,社会的方方面面、各行各业都在努力与现代的先进技术接轨,通过科技手段来提高自身的优势,蜗牛兼职网当然也不能排除在外。蜗牛兼职网是以实际运用为开发背景,运用软件工程原理和开发方法,采用springbo......