字典树整理

2022/03/27

题目一:字典序的第k小数字
字典树的思想 一个有9棵树的森林 每个结点包含10棵子树 关键在于求出每个子树中共包含多少个结点(包含根节点本身)
假设当前要求第k小结点 此时求出结点root的第一个树中结点个数为i个,curr来表示当前所在结点所对应的数字,最一开始的时候为1,即curr=1;
假设i<=step(step=k-1 减1是因为要减去当前结点本身)
那么说明走掉i步之后 还没有到达第k小的数字 所以肯定不在第1个树中 则向后查找i个后来到了curr相邻的右边的兄弟结点 即来到了第2棵树 此时step-step-i ,curr=curr+1;
如果i>step
那么则说明第k小的数字 在curr的子树之中,则应进一步缩小范围,向下查找
此时curr=curr*10,同时向下走一步后step=step-1;

class Solution {
public: 
   int getSteps(int curr,long n)     //计算当前结点有多少个子节点
   {
      long first=curr,end=curr,ans=0;
      while(first<=n)
      {
          ans += min(end, n) - first + 1;
          first=first*10;
          end=end*10+9;
      }
      return ans;
   }

    int findKthNumber(int n, int k) {
        int curr = 1 , step = k-1;
        long long  e;
        while(step>0)
        {
            e=getSteps(curr,n);
            cout<<e<<endl;
            if(e>step)
            {
                curr=curr*10;
                step--;
            }
            else
            { 
                curr=curr+1;
                step=step-e;
            }
        }
        return curr;
    }
};

题目二:词典中最长的单词
思路:root作为根节点 每个根节点包含26个子节点 初始化全都为nullptr 然后插入单词 在插入过程中 如果需要将对应位置的nullptr进行赋值 同时用isend来标记从根节点到该节点是否存在一个单词 isend=true表示存在对应单词 否则则表示根节点到该节点只是一个前缀

class tree{
public:
   //构造函数
   tree(){
    children =  vector<tree *>(26,nullptr);
    end=false;
   }

   //插入某个字母
   bool insert(string word)
   {
      tree * node=this;
      for(int i=0;i<word.length();i++)
      {
          int pos=word[i]-'a';
          if(node->children[pos]==nullptr)
          node->children[pos]=new tree();
          node=node->children[pos];
      }
      node->end=true;
      return true;
   }
   //查找某个字符串是不是在字典树中  保证每一步中经过的结点对应的end都是true;
   bool  search(string word)
   {
      tree * node=this;
      for(int i=0;i<word.length();i++)
      {
          int pos=word[i]-'a';
          if(node->children[pos]==nullptr || node->children[pos]->end==false)
          return false;
          node=node->children[pos];
      }
    return true;
   }
private:
   vector<tree *>  children ;
   bool end;
};

class Solution {
public:
    string longestWord(vector<string>& words) {
    string ans="";
    tree  root;
    for(int i=0;i<words.size();i++)
    {
         root.insert(words[i]);
    }
    for(int i=0;i<words.size();i++)
    {
         if(root.search(words[i]))
         {
             if(words[i].length()>ans.length() || (words[i].length()==ans.length() && words[i]<ans ))
             ans=words[i];
         }
    }
    return ans;
    }
};

题目三:

持续更新…

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值