Trie树与位操作

本文介绍了如何使用Trie树解决数字位操作问题,包括找到两个元素的最大异或值、子数组最大异或和以及满足特定XOR条件的子数组数量。通过插入和查询操作,利用Trie树的特性,可以高效地处理这些问题。
摘要由CSDN通过智能技术生成

使用Trie树解决数字位操作问题。

Trie树

Trie树可以将keys/numbers/strings等信息保存在树中。
Trie树由一系列结点组成,每个结点存储一个字符/位。从而我们可以插入新的strings/numbers。
以trie树存储strings为例:
trie1.png

但现在我们要用trie树解决数字问题,特别是二进制位。问题如下:

Problem1: Given an array of integers, we have to find two elements whose XOR is maximum.

Solution:
假设有一种数据结构可以满足两种查询操作:
+1.插入一个数值X
+2.给定Y,找到目前已经插入的所有数据中与Y相异或(XOR)结果的最大值
如果有这样的数据结构,那就依次插入数据,查询最大值,从而获得最终的最大值。
trie树就是我们将要使用的数据结构。
首先,看看如何在trie树中插入元素。
trie2.png

所以,只需要记录数字需要插入的路径,不必管已经存在的路径。
插入长度为N的key的时间复杂度O(N),O(N)就是log2(MAX),M

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是一个简单的 C 语言字典 Trie 的代码实现: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_WORD_LEN 100 typedef struct TrieNode { char value; struct TrieNode *children[26]; int is_end; } TrieNode; TrieNode *createNode(char value) { TrieNode *node = (TrieNode *) malloc(sizeof(TrieNode)); node->value = value; for (int i = 0; i < 26; i++) { node->children[i] = NULL; } node->is_end = 0; return node; } void insert(TrieNode *root, char *word) { TrieNode *curr = root; int len = strlen(word); for (int i = 0; i < len; i++) { int index = word[i] - 'a'; if (curr->children[index] == NULL) { curr->children[index] = createNode(word[i]); } curr = curr->children[index]; } curr->is_end = 1; } int search(TrieNode *root, char *word) { TrieNode *curr = root; int len = strlen(word); for (int i = 0; i < len; i++) { int index = word[i] - 'a'; if (curr->children[index] == NULL) { return 0; } curr = curr->children[index]; } return curr->is_end; } int main() { TrieNode *root = createNode('\0'); char word[MAX_WORD_LEN]; int choice = 0; do { printf("1. Insert Word\n"); printf("2. Search Word\n"); printf("3. Exit\n"); printf("Enter Choice: "); scanf("%d", &choice); switch (choice) { case 1: printf("Enter Word to Insert: "); scanf("%s", word); insert(root, word); break; case 2: printf("Enter Word to Search: "); scanf("%s", word); if (search(root, word)) { printf("%s is present in the dictionary.\n", word); } else { printf("%s is not present in the dictionary.\n", word); } break; case 3: printf("Exiting...\n"); break; default: printf("Invalid Choice!\n"); break; } } while (choice != 3); return 0; } ``` 该实现中使用了一个 TrieNode 结构体来表示 Trie 中的每个节点,其中包含了节点的值,子节点指针数组和一个标志,用于指示该节点是否为单词的结尾。 在插入单词时,从根节点开始遍历 Trie ,如果当前节点的相应子节点为空,则新建一个节点并将其作为当前节点的相应子节点。最后将单词的结尾节点的标志设置为 1。 在查找单词时,同样从根节点开始遍历 Trie ,如果当前节点的相应子节点为空,则说明该单词不存在于 Trie 中。如果单词的最后一个字符所在的节点的标志为 1,则说明该单词存在于 Trie 中。 该实现中还包含了一个简单的命令行界面,用于接收用户的输入并执行相应的操作。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值