677-键值映射(Map Sum Pairs)
前言
前缀树同系列的题目,可以用前缀树的思路来存储,只需要基于之前的前缀树实现改造。原题目要求如下:
实现一个 MapSum 类里的两个方法,insert 和 sum。对于方法 insert,你将得到一对(字符串,整数)的键值对。字符串表示键,整数表示值。如果键已经存在,那么原来的键值对将被替代成新的键值对。
对于方法 sum,你将得到一个表示前缀的字符串,你需要返回所有以该前缀开头的键的值的总和。
示例 1:
输入: insert("apple", 3), 输出: Null
输入: sum("ap"), 输出: 3
输入: insert("app", 2), 输出: Null
输入: sum("ap"), 输出: 5
实现思路
- 参考前缀树实现的思路,把节点中的boolean变量改为键值对的值
- sum方法的时候首先要找到匹配前缀的节点,然后用层序遍历(广度优先)方式去遍历这个节点的子树。遍历的时候使用递归进行遍历。
实例代码
public class MapSum {
/**
* key的前缀字符
*/
char keyPrefix;
/**
* 子节点
*/
MapSum[] children;
/**
* 存储的值,不为0则为终止节点
*/
int value;
/** Initialize your data structure here. */
public MapSum() {
children=new MapSum[26];
value=0;
}
/**
* 字符串表示键,整数表示值。如果键已经存在,那么原来的键值对将被替代成新的键值对。
* @param key 键
* @param val 值
*/
public void insert(String key, int val) {
if(key!=null){
//分解成字符数组
char[] charArr=key.toCharArray();
//模拟指针操作,记录当前访问到的树的节点
MapSum currentNode=this;
for(int i=0;i<charArr.length;i++){
char currentChar=charArr[i];
//根据字符获取对应的子节点
MapSum node=currentNode.children[currentChar-97];
if(node!=null && node.keyPrefix==currentChar){//判断节点是否存在
currentNode=node;
}else{//不存在则创建一个新的叶子节点,并指向当前的叶子节点
node=new MapSum();
node.keyPrefix=currentChar;
currentNode.children[currentChar-97]=node;
currentNode=node;
}
}
//存储值
currentNode.value=val;
}else{
this.value=val;
}
}
/**
* 根据表示前缀的字符串,返回所有以该前缀开头的键的值的总和。
* @param prefix 前缀
* @return
*/
public int sum(String prefix) {
int result=0;
//前缀是否匹配
boolean match=true;
if(prefix!=null && !prefix.trim().equals("")){
char[] prefixChar=prefix.toCharArray();
MapSum currentNode=this;
for(int i=0;i<prefixChar.length;i++){
char currentChar=prefixChar[i];
MapSum node=currentNode.children[currentChar-97];
if(node!=null && node.keyPrefix==currentChar){//判断节点是否存在
currentNode=node;
}else{
match=false;
break;
}
}
if(match){//前缀匹配后开始检索这个匹配节点后续的子树
result=sumByFloor(currentNode);
}
}
return result;
}
/**
* 层序遍历(广度优先)方式访问树
* @param mapSum
* @return
*/
private int sumByFloor(MapSum mapSum){
int result=0;
if(mapSum==null){
return 0;
}else{
result+=mapSum.value;
MapSum[] mapSums=mapSum.children;
for(MapSum sum:mapSums){
if(sum!=null){
result+=sumByFloor(sum);
}else{
result+=sumByFloor(sum);
}
}
}
return result;
}
}
技术杂谈
最近工作比较忙,专栏内容主要为一些自己的学习笔记
推荐阅读
谈谈你所不知道的ArrayList缩容
每当大家谈起ArrayList都只会关注它的自动扩容机制,但是大多数人却不会去关注ArrayList是否会自动缩容。下面会根据几个问题让大家了解一下ArrayList的缩容机制。
Null赞 2阅读 2.2k
一文搞懂秒杀系统,欢迎参与开源,提交PR,提高竞争力。早日上岸,升职加薪。
前言秒杀和高并发是面试的高频考点,也是我们做电商项目必知必会的场景。欢迎大家参与我们的开源项目,提交PR,提高竞争力。早日上岸,升职加薪。知识点详解秒杀系统架构图秒杀流程图秒杀系统设计这篇文章一万多...
王中阳Go赞 32阅读 2.4k评论 1
计算机网络连环炮40问
本文已经收录到Github仓库,该仓库包含计算机基础、Java基础、多线程、JVM、数据库、Redis、Spring、Mybatis、SpringMVC、SpringBoot、分布式、微服务、设计模式、架构、校招社招分享等核心知识点,欢迎star~
程序员大彬赞 14阅读 1.7k
万字详解,吃透 MongoDB!
MongoDB 是一个基于 分布式文件存储 的开源 NoSQL 数据库系统,由 C++ 编写的。MongoDB 提供了 面向文档 的存储方式,操作起来比较简单和容易,支持“无模式”的数据建模,可以存储比较复杂的数据类型,是一款非常...
JavaGuide赞 8阅读 1.6k
花了半个小时基于 ChatGPT 搭建了一个微信机器人
相信大家最近被 ChatGPT 刷屏了,其实在差不多一个月前就火过一次,不会那会好像只在程序员的圈子里面火起来了,并没有被大众认知到,不知道最近是因为什么又火起来了,而且这次搞的人尽皆知。
Java极客技术赞 12阅读 3.1k评论 3
数据结构与算法:二分查找
一、常见数据结构简单数据结构(必须理解和掌握)有序数据结构:栈、队列、链表。有序数据结构省空间(储存空间小)无序数据结构:集合、字典、散列表,无序数据结构省时间(读取时间快)复杂数据结构树、 堆图二...
白鲸鱼赞 9阅读 5.2k
PHP转Go实践:xjson解析神器「开源工具集」
我和劲仔都是PHP转Go,身边越来越多做PHP的朋友也逐渐在用Go进行重构,重构过程中,会发现php的json解析操作(系列化与反序列化)是真的香,弱类型语言的各种隐式类型转换,很大程度的减低了程序的复杂度。
王中阳Go赞 11阅读 2.7k评论 4
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。