问题描述
实现一个 MapSum 类,支持两个方法,insert 和 sum:
MapSum() 初始化 MapSum 对象
void insert(String key, int val) 插入 key-val 键值对,字符串表示键 key ,整数表示值 val 。如果键 key 已经存在,那么原来的键值对将被替代成新的键值对。
int sum(string prefix) 返回所有以该前缀 prefix 开头的键 key 的值的总和。
示例:
输入:
[“MapSum”, “insert”, “sum”, “insert”, “sum”] [[], [“apple”, 3],
[“ap”], [“app”, 2], [“ap”]] 输出: [null, null, 3, null, 5]解释:
MapSum mapSum = new MapSum(); mapSum.insert(“apple”, 3);
mapSum.sum(“ap”); // return 3 (apple = 3)
mapSum.insert(“app”, 2);
mapSum.sum(“ap”); // return 5
(apple + app = 3 + 2 = 5)
提示:
1 <= key.length, prefix.length <= 50
key 和 prefix 仅由小写英文字母组成
1 <= val <= 1000
最多调用 50 次 insert 和 sum
解题思路
在java中,键值对的数据结构可以用Map集合来表示,Map集合的实现类有HashMap,TreeMap和LinkedHashMap以及后来的ConcurrentHashMap等。其中
HashMap是基于哈希表的形式实现的,元素之间不可重复,无序。
TreeMap是基于有序树的形式来实现的,元素之间按照一定的顺序组织在一起(这里不是指插入的顺序)
LinkedHashMap基于链表的形式实现的,元素之间按照插入的顺序组织在一起
ConcurrentHashMap与HashMap类似,但是实现上增加了多线程安全的机制
本题中,显然可以使用Map来实现,实现类可以选择HashMap
在初始化MapSum对象的时候,即可new一个HashMap,注意,这里为了保证在每个方法里面都可以访问到我们的HashMap对象,我们把对象引用的声明定义为成员变量。
插入的时候使用Map集合提供的put方法即可,由于HashMap不允许重复元素,因此如果key已存在,则value会被覆盖
在sum的时候,我们需要需要得到map中的所有的键,因此我们可以使用keySet方法,用set集合来保存所有的键。最终通过给定字符串的长度值,来匹配所有键的前面该长度的字符串部分是否与给定字符串相同。具体代码如下:
代码实现
```java
class MapSum {
Map<String,Integer> maps;
/** Initialize your data structure here. */
//初始化map对象,使用HashMap存储结构
public MapSum() {
maps=new HashMap<String,Integer>();
}
public void insert(String key, int val) {
//HashMap已经不允许键重复,如果重复,则覆盖
maps.put(key,val);
}
public int sum(String prefix) {
//使用keySet方法得到所有的键
Set<String> sets=maps.keySet();
int result=0;
int len=prefix.length();
for(String s:sets){
//如果给定前缀的长度比键的长度还长,那么给定的这个字符串一定不是该键的前缀
if(s.length()>=len){
//使用substring找到该长度下的子字符串
String sub=s.substring(0,len);
if(sub.equals(prefix)){
int temp=maps.get(s);
result+=temp;
}
}
}
return result;
}
}