421. 数组中两个数的最大异或值
给定一个非空数组,数组中元素为 a0, a1, a2, … , an-1,其中 0 ≤ ai < 2^31 。
找到 ai 和aj 最大的异或 (XOR) 运算结果,其中0 ≤ i, j < n 。
你能在O(n)的时间解决这个问题吗?
class Solution { public: int Max_xor=-1; string numToBinaryString(int n){ string res=""; for(int i=0;i<31;i++){ if(( n & 1 )== 0)res="0"+res; else res="1"+res; n = n >> 1; } return res; } void MXOR(TreeNode* p, TreeNode* q,int k){ if(p->val+q->val==1)k = k << 1 | 1; else k = k << 1; int c1=(p->left!=NULL)+(p->right!=NULL),c2=(q->left!=NULL)+(q->right!=NULL); if(c1==0&&c2==0){ Max_xor=max(Max_xor,k); return; } if(c1==2&&c2==2){ MXOR(p->left,q->right,k); MXOR(p->right,q->left,k); } else if(c1==2&&c2==1){ if(q->left) MXOR(p->right,q->left,k); else MXOR(p->left,q->right,k); } else if(c1==1&&c2==2){ if(p->left) MXOR(p->left,q->right,k); else MXOR(p->right,q->left,k); } else{ TreeNode* a=p->left==NULL?p->right:p->left; TreeNode* b=q->left==NULL?q->right:q->left; MXOR(a,b,k); } } int findMaximumXOR(vector<int>& nums) { TreeNode* root=new TreeNode(0); TreeNode* p; for(int i=0;i<nums.size();i++){ string res=numToBinaryString(nums[i]); p=root; int k=0; for(int j=0;j<res.length();j++){ if(res[j]=='0'){ if(p->left==NULL){ TreeNode* tmp=new TreeNode(0); p->left=tmp; } p=p->left; } else{ if(p->right==NULL){ TreeNode* tmp=new TreeNode(1); p->right=tmp; } p=p->right; } } } int k=0; while((!root->left||!root->right)&&(root->left||root->right)){ if(!root->left){ root=root->right; } else{ root=root->left; } } if(root->left==NULL&&root->right==NULL)return 0; MXOR(root->left, root->right,0); return Max_xor; } };
面试题 17.17. 多次搜索
给定一个较长字符串big和一个包含较短字符串的数组smalls,设计一个方法,根据smalls中的每一个较短字符串,对big进行搜索。输出smalls中的字符串在big里出现的所有位置positions,其中positions[i]为smalls[i]出现的所有位置。
输入:
big = "mississippi"
smalls = ["is","ppi","hi","sis","i","ssippi"]
输出: [[1,4],[8],[],[3],[1,4,7,10],[5]]
根据smalls来创建字典树,对big中逐位进行字典树搜索,字典树的节点上加上end标志标记单词结束
class Solution { public: struct Trie{ char val; bool end; Trie* next[26]={NULL}; Trie(char c,bool flag):val(c),end(flag){} }; void creatTrie(string& s,Trie* root){ //将字符串插入到字典树中 Trie* tmp=root; for(int i=0;i<s.length();i++){ if(tmp->next[s[i]-'a']==NULL){ Trie* newNode; if(i==s.length()-1) newNode=new Trie(s[i],true); else newNode=new Trie(s[i],false); tmp->next[s[i]-'a']=newNode; } tmp=tmp->next[s[i]-'a']; } tmp->end=true; //字符串结尾结点设置结束标志为true } vector<vector<int>> multiSearch(string big, vector<string>& smalls) { unordered_map<string, int> mp; for(int i=0;i<smalls.size();i++){ mp[smalls[i]]=i; } //map保存字符串在smalls中的下标 Trie* root=new Trie('*',false); for(string& s:smalls){ creatTrie(s,root); } //构建字典树 vector<vector<int>> ans(smalls.size(),vector<int>()); for(int i=0;i<big.length();i++){ Trie* tmp=root; string stmp=""; //字典路径上的字符串 int tag=i; while(tag<big.length()&&tmp->next[big[tag]-'a']!=NULL){ stmp+=big[tag]; tmp=tmp->next[big[tag]-'a']; if(tmp->end==true)ans[mp[stmp]].push_back(i); //找到结束标记,说明stmp是smalls中的一个字符串 tag++; } } return ans; } };