leetcode设计类题目——677. 键值映射
Posted C_YCBX Py_YYDS
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leetcode设计类题目——677. 键值映射相关的知识,希望对你有一定的参考价值。
题目
需求分析
需求:
- 插入单词与值形成联系
- 查询前缀对应的所有单词的值的和
- 很明显,直接用字典树便可完成这个需求。
但有一个问题:如何快速得到这个前缀对应的所有单词的和?
很简单的处理方式就是利用哈希表对每个单词的权值进行记录 ,如果出现替换键值映射的情况,那就将这次的加和值减去原来的值。
当然也可不用哈希表,直接多设置一个 f
标记用于区分单词结尾,顺便记录这个单词对应的权值,如果出现键值替换的情况,直接就将这个值从头再减去一遍即可。
代码部分
解题代码:
struct str{//用于标记是否存在这个单词,且保存它对应的权值
int v;
str(int v):v(v){}
};
struct node{//字典树的结点
str* f;
int w;
node* next[26];
node(int w):w(w),f(nullptr){
memset(next,0,sizeof(node*)*26);
}
};
class MapSum {
public:
node* head;
MapSum() {
head = new node(0);
}
void insert(string key, int val) {
//思路很简单,就是插入的时候把经过的路径上加上之前的带权值
int pos;
node* root = head;
for(auto&& ch:key){
pos = ch-'a';
if(root->next[pos] == 0){
root->next[pos] = new node(val);
}else{
root->next[pos]->w += val;
}
root = root->next[pos];
}
if(root->f){//如果这个键值已经存在,则往回减去这个 v 值
int _val = root->f->v;
node* _root = head;
for(auto&&ch : key){
pos = ch-'a';
_root->next[pos]->w -= _val;
_root = _root->next[pos];
}
_root->f->v = val;
}else{
root->f = new str(val);
}
}
int sum(string prefix) {
node* root = head;
for(auto&& ch: prefix){//由于w直接就记录了整个带权路径和,所以只要找到prefix的终点即可
if(root->next[ch-'a']!=0)
root = root->next[ch-'a'];
else
return 0;
}
return root->w;
}
};
工业化代码:
struct str{//用于标记是否存在这个单词,且保存它对应的权值
int v;
str(int v):v(v){}
};
struct node{//字典树的结点
str* f;
int w;
node* next[26];
node(int w):w(w),f(nullptr){
memset(next,0,sizeof(node*)*26);
}
};
class MapSum {
private:
void destroy(node* root){
if(!root)
return;
for(int i=0;i<26;i++){
if(root->next[i]){
destroy(root->next[i]);
}
}
if(root->f)
delete root->f;
delete root;
}
public:
node* head;
MapSum() {
head = new node(0);
}
~MapSum() {
destroy(head);
}
void insert(string key, int val) {
//思路很简单,就是插入的时候把经过的路径上加上之前的带权值
int pos;
node* root = head;
for(auto&& ch:key){
pos = ch-'a';
assert(root != 0); //老师说工业界代码要加几个断言
if(root->next[pos] == 0){
root->next[pos] = new node(val);
}else{
root->next[pos]->w += val;
}
root = root->next[pos];
}
if(root->f){//如果这个键值已经存在,则往回减去这个 v 值
int _val = root->f->v;
node* _root = head;
for(auto&&ch : key){
pos = ch-'a';
_root->next[pos]->w -= _val;
_root = _root->next[pos];
}
_root->f->v = val;
}else{
root->f = new str(val);
}
}
int sum(string prefix) {
node* root = head;
for(auto&& ch: prefix){//由于w直接就记录了整个带权路径和,所以只要找到prefix的终点即可
assert(root != 0);
if(root->next[ch-'a']!=0)
root = root->next[ch-'a'];
else
return 0;
}
return root->w;
}
};
以上是关于leetcode设计类题目——677. 键值映射的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode 520. 检测大写字母 / 677. 键值映射 / 319. 灯泡开关
LeetCode 677 键值映射[Map] HERODING的LeetCode之路