最近看到YELP的电面有问到字符串的一道题, 搜了一下 发现了 TRIE 字典树, 学一下~

Implement a trie with insert, search, and startsWith methods.
Note:
You may assume that all inputs are consist of lowercase letters a-z.

Trie树又被称为字典树、前缀树,是一种用于快速检索的多叉树。Tried树可以利用字符串的公共前缀来节省存储空间。
但如果系统存在大量没有公共前缀的字符串,相应的Trie树将非常消耗内存。(下图为Wiki上的Trie树示意图, Wiki


Trie树的基本性质如下:
• 根节点不包括字符,除根节点外每个节点包括一个支付。
• 从根节点到某一节点,路径上经过的字符连接起来,即为对应的字符串。
• 每个节点的所有子节点包含的字符串各不相同。
本题中的Trie树可以简单实现如下:
Trie树节点数据结构定义如下:

1.    val表示该节点对应的字符
2.    子节点简单用一个数组表示,这样实现比较简单,但比较耗费内存
3.    isWord标记从根节点到该节点是否表示一个单词,还是另一单词的前缀。
    1.    class TrieNode {  
    2.    public:  
    3.        char var;  
    4.        bool isWord;  
    5.        TrieNode* children[26];  
    6.        // Initialize your data structure here.  
    7.        TrieNode() {  
    8.            var = 0;  
    9.            isWord = false;  
    10.            memset(children, 0x0, sizeof(TreeNode*)*26);  
    11.      
    12.        }  
    13.        TrieNode(char c){  
    14.            var = c;  
    15.            isWord = false;  
    16.            memset(children, 0x0, sizeof(TreeNode*)*26);  
    17.        }  
    18.    };

Trie树的实现算法如下:

    1.    class Trie {  
    2.    public:  
    3.        Trie() {  
    4.            root = new TrieNode();  
    5.        }  
    6.      
    7.        // Inserts a word into the trie.  
    8.        void insert(string word) {  
    9.            TrieNode* pNode = root;  
    10.            if (word.length() <= 0)  
    11.            {  
    12.                return;  
    13.            }  
    14.            for (int i= 0; i<word.length(); i++)  
    15.            {  
    16.                char c= word[i];  
    17.                if (pNode->children[c-'a'] == 0)  
    18.                {  
    19.                    TrieNode *pNew = new TrieNode(c);  
    20.                    pNode->children[c-'a'] = pNew;  
    21.                }  
    22.                pNode = pNode->children[c-'a'];  
    23.            }  
    24.            pNode->isWord = true;  
    25.        }  
    26.      
    27.        // Returns if the word is in the trie.  
    28.        bool search(string word) {  
    29.            TrieNode *pNode = root;  
    30.            if (word.length() <= 0)  
    31.                return true;  
    32.            for (int i =0; i<word.length(); i++)  
    33.            {  
    34.                char c = word[i];  
    35.                pNode = pNode->children[c-'a'];  
    36.                if (pNode == NULL)  
    37.                    return false;  
    38.            }  
    39.            return pNode->isWord;  
    40.        }  
    41.      
    42.        // Returns if there is any word in the trie  
    43.        // that starts with the given prefix.  
    44.        bool startsWith(string prefix) {  
    45.            TrieNode *pNode = root;  
    46.            if (prefix.length()<=0)  
    47.                return true;  
    48.            for (int i=0; i<prefix.length(); i++)  
    49.            {  
    50.                char c = prefix[i];  
    51.                pNode = pNode->children[c-'a'];  
    52.                if (pNode == NULL)  
    53.                    return false;  
    54.            }  
    55.            return true;  
    56.        }  
    57.        void freeTrieNode(TrieNode* pNode){  
    58.            if (pNode == NULL)  
    59.                return;  
    60.            for (int i=0; i<26;i++)  
    61.            {  
    62.                TrieNode* pChild = pNode->children[i];  
    63.                if (pChild != NULL)  
    64.                {  
    65.                    freeTrieNode(pChild);  
    66.                }  
    67.            }  
    68.            free(pNode);  
    69.        }  
    70.        ~Trie(){  
    71.            freeTrieNode(root);  
    72.        }  
    73.    private:  
    74.        TrieNode* root;  
    75.    };

下面是PYTHON的一个实现

准备就常用的数据结构写一个REP吧/

class TrieTree(object):

  def __init__(self):
    self.tree = {}

  def add(self, word):
    tree = self.tree

    for char in word:
      if char in tree:
        tree = tree[char]
      else:
        tree[char] = {}
        tree = tree[char]

    tree['exist'] = True

  def search(self, word):
    tree = self.tree

    for char in word:
      if char in tree:
        tree = tree[char]
      else:
        return False

    if "exist" in tree and tree["exist"] == True:
      return True
    else:
      return False

tree = TrieTree()
tree.add("abc")
tree.add("bcd")
print(tree.tree)
# Print {'a': {'b': {'c': {'exist': True}}}, 'b': {'c': {'d': {'exist': True}}}}
print(tree.search("ab"))
# Print False
print(tree.search("abc"))
# Print True
print(tree.search("abcd"))
# Print False

trivial example

leetcode第一题, two sum,

这个了有点时间… 我在复制数组的时候直接用的a = b, 但是在PYTHON里面这样拷贝会把地址也传递过去, 当del a[2]的时候也会改变b的值, 开始没有注意, 所以老是出错, 这题还是比较简单的一道题 = =

class Solution(object):
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        for i in nums:
            dif = target - i
            nums1 = nums[:]
            a = nums1.index(i)
            del nums1[a]
            if dif in nums1 :
                b = nums1.index(dif) + 1
                return [a,b]


话说还是第一次在leetcode上面做题, 以后没事多来刷一下吧~~ 以后面试也好弄..

开一个rep来记录一下