【乱七八糟的笔记】——前缀树

本文详细介绍了前缀树的构建、插入和搜索,以及前缀树的哈希表和数组实现方式。同时,文章探讨了前缀和数组在处理一维和二维数组中的应用,包括303. 区域和检索 - 数组不可变、724. 寻找数组的中心下标等题目,讲解了如何通过前缀和优化解题效率。
摘要由CSDN通过智能技术生成

前缀树的构建

  • 利用数组构建
// change this value to adapt to different cases
#define N 26

struct TrieNode {
    TrieNode* children[N];
    
    // you might need some extra values according to different cases
};

/** Usage:
 *  Initialization: TrieNode root = new TrieNode();
 *  Return a specific child node with char c: (root->children)[c - 'a']
 */
class TrieNode{  // 前缀树节点的实现
public:
    TrieNode* children[26]; // 前缀树可以存储26个小写字母,存在next数组中。
    bool flage;
    TrieNode() { // 构造函数
        memset(children, NULL, sizeof(children)); // 分配空间
        flage = false;
    }
    ~TrieNode() { // 析构函数。此处可以不写,实际中写上较好。
        for (int i = 0; i < 26; i++) {
            if(children[i]) delete children[i];
        }
    }
};

  访问子节点更加快捷,且容易,但并非所有子节点都会用到,会造成空间的浪费。

  • 利用哈希表构建
struct TrieNode {
    unordered_map<char, TrieNode*> children;
    
    // you might need some extra values according to different cases
};

/** Usage:
 *  Initialization: TrieNode root = new TrieNode();
 *  Return a specific child node with char c: (root->children)[c]
 */

  访问子节点更加容易,但速度稍慢,但方法较为灵活,不会收到固定长度、范围的限制。

前缀树的插入

Initialize: cur = root
for each char c in target string S:
	if cur does not have a child c:
		cur.children[c] = new Trie node
	cur = cur.children[c]
cur is the node which represents the string S

前缀树的搜索

Initialize: cur = root
for each char c in target string S:
	if cur does not have a child c:
		search fails
	cur = cur.children[c]
search successes

前缀树的实现

struct TrieNode {
    bool flag;
    map<char, TrieNode*> next; 
};
class Trie {
private:
    TrieNode* root;
    
public:
    /** Initialize your data structure here. */
    Trie() {
        root = new TrieNode();
    }
    
    /** Inserts a word into the trie. */
    void insert(string word) {
        TrieNode* p = root;
        for (int i = 0; i < word.length(); ++i) {
            if ((p->next).count(word[i]) <= 0) {
                // insert a new node if the path does not exist
                (p->next).insert(make_pair(word[i], new TrieNode()));
            }
            p = (p->next)[word[i]];
        }
        p->flag = true;
    }
    
    /** Returns if the word is in the trie. */
    bool search(string word) {
        TrieNode* p = root;
        for (int i = 0; i < word.length(); ++i) {
            if ((p->next).count(word[i]) <= 0) {
                return false;
            }
            p = (p->next)[word[i]];
        }
        return p->flag;
    }
    
    /** Returns if there is any word in the trie that starts with the given prefix. */
    bool startsWith(string prefix) {
        TrieNode* p = root;
        for (int i = 0; i < prefix.length(); ++i) {
            if ((p->next).count(prefix[i]) <= 0) {
                return false;
            }
            p = (p->next)[prefix[i]];
        }
        return true;
    }
};

/**
 * Your Trie object will be instantiated and called as such:
 * Trie obj = new Trie();
 * obj.insert(word);
 * bool param_2 = obj.search(word);
 * bool param_3 = obj.startsWith(prefix);
 */

前缀和数组

注意的点 为了省去边界判断,前缀和数组多开辟一个 从1到n

class PrefixSum {
private:
  // 前缀和数组
  vector<int> prefix;
  
public:
  /* 输入一个数组,构造前缀和 */
  PrefixSum(vector<int> nums) {
    int n = nums.size();
    prefix.resize(n+1);
    // 计算 nums 的累加和
    for (int i = 1; i <= n; i++) {
      prefix[i] = prefix[i - 1] + nums[i - 1];
    }
  }

  /* 查询闭区间 [i, j] 的累加和 */
  int query(int i, int j) {
    return prefix[j + 1] - prefix[i];
  }
};

一维数组中的前缀和

303. 区域和检索 - 数组不可变

labuladong 题解思路

给定一个整数数组 nums,处理以下类型的多个查询:

  1. 计算索引 leftright (包含 leftright)之间的 num
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

甄姬、巴豆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值