LeetCode 230. 二叉搜索树中第K小的元素 / 476. 数字的补数 / 211. 添加与搜索单词 - 数据结构设计(字典树)
Posted Zephyr丶J
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 230. 二叉搜索树中第K小的元素 / 476. 数字的补数 / 211. 添加与搜索单词 - 数据结构设计(字典树)相关的知识,希望对你有一定的参考价值。
230. 二叉搜索树中第K小的元素
2021.10.17 每日一题
题目描述
给定一个二叉搜索树的根节点 root ,和一个整数 k ,请你设计一个算法查找其中第 k 个最小元素(从 1 开始计数)。
示例 1:
输入:root = [3,1,4,null,2], k = 1
输出:1
示例 2:
输入:root = [5,3,6,2,4,null,null,1], k = 3
输出:3
提示:
树中的节点数为 n 。
1 <= k <= n <= 10^4
0 <= Node.val <= 10^4
进阶:如果二叉搜索树经常被修改(插入/删除操作)并且你需要频繁地查找第 k 小的值,你将如何优化算法?
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/kth-smallest-element-in-a-bst
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
因为是二叉搜索树,所以中序遍历是从小到大排列的,所以中序遍历即可
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
int k;
TreeNode t = null;
public int kthSmallest(TreeNode root, int k) {
//第k小就是从小到大数第k个
//就是中序遍历的第k个节点
this.k = k;
inorder(root);
return t.val;
}
public void inorder(TreeNode node){
if(node == null)
return;
if(t != null)
return;
inorder(node.left);
if(--k == 0)
t = node;
inorder(node.right);
}
}
迭代写法
class Solution {
public int kthSmallest(TreeNode root, int k) {
//写个中序遍历的迭代写法
Stack<TreeNode> stack = new Stack<>();
while(root != null || !stack.isEmpty()){
while(root != null){
stack.push(root);
root = root.left;
}
root = stack.pop();
if(--k == 0)
return root.val;
root = root.right;
}
return root.val;
}
}
476. 数字的补数
2021.10.18 每日一题
题目描述
对整数的二进制表示取反(0 变 1 ,1 变 0)后,再转换为十进制表示,可以得到这个整数的补数。
例如,整数 5 的二进制表示是 “101” ,取反后得到 “010” ,再转回十进制表示得到补数 2 。
给你一个整数 num ,输出它的补数。
示例 1:
输入:num = 5
输出:2
解释:5 的二进制表示为 101(没有前导零位),其补数为 010。所以你需要输出 2 。
示例 2:
输入:num = 1
输出:0
解释:1 的二进制表示为 1(没有前导零位),其补数为 0。所以你需要输出 0 。
提示:
1 <= num < 2^31
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/number-complement
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
先求出这个数有几位,然后每一位取反
class Solution {
public int findComplement(int num) {
//先求出有几位,然后挨个取反
int n = 0;
while((1 << n) < num){
n++;
if(n == 31)
break;
}
int res = 0;
for(int i = 1; i <= n; i++){
res = (res << 1) + (((num >> (n - i)) & 1) ^ 1);
}
return res;
}
}
这里取反的操作,可以是num与mask异或
mask是num所有位都为1,这样也可以达到效果,因为这样异或,原来是0将变成1,原来是1将变成0
三叶姐的方法,先lowbit操作,即每次减去一个位置的1,找到最高位的1,假设是x,那么x-1就是除了最高位所有位都是1;然后可以采用异或的方法,也可以和三叶姐一样,采用取反然后相与的方法
class Solution {
public int findComplement(int num) {
int x = 0;
for(int i = num; i != 0; i -= i & (-i))
x = i;
//取反相与
return (x - 1) & ~num;
//return (x - 1) ^ (num - x);
}
}
211. 添加与搜索单词 - 数据结构设计
2021.10.19 每日一题
题目描述
请你设计一个数据结构,支持 添加新单词 和 查找字符串是否与任何先前添加的字符串匹配 。
实现词典类 WordDictionary :
WordDictionary() 初始化词典对象
void addWord(word) 将 word 添加到数据结构中,之后可以对它进行匹配
bool search(word) 如果数据结构中存在字符串与 word 匹配,则返回 true ;否则,返回 false 。word 中可能包含一些 ‘.’ ,每个 . 都可以表示任何一个字母。
示例:
输入:
[“WordDictionary”,“addWord”,“addWord”,“addWord”,“search”,“search”,“search”,“search”]
[[],[“bad”],[“dad”],[“mad”],[“pad”],[“bad”],[".ad"],[“b…”]]
输出:
[null,null,null,null,false,true,true,true]
解释:
WordDictionary wordDictionary = new WordDictionary();
wordDictionary.addWord(“bad”);
wordDictionary.addWord(“dad”);
wordDictionary.addWord(“mad”);
wordDictionary.search(“pad”); // return False
wordDictionary.search(“bad”); // return True
wordDictionary.search(".ad"); // return True
wordDictionary.search(“b…”); // return True
提示:
1 <= word.length <= 500
addWord 中的 word 由小写英文字母组成
search 中的 word 由 ‘.’ 或小写英文字母组成
最多调用 50000 次 addWord 和 search
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/design-add-and-search-words-data-structure
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
字典树加深度优先搜索,因为有点的存在
class WordDictionary {
//自己写一遍
private boolean isEnd;
private WordDictionary[] next;
public WordDictionary() {
isEnd = false;
next = new WordDictionary[26];
}
public void addWord(String word) {
WordDictionary wd = this;
int l = word.length();
for(int i = 0; i < l; i++){
int t = word.charAt(i) - 'a';
if(wd.next[t] == null)
wd.next[t] = new WordDictionary();
wd = wd.next[t];
}
wd.isEnd = true;
}
public boolean search(String word) {
//想想怎么处理点
WordDictionary wd = this;
int l = word.length();
return dfs(wd, word, 0);
}
public boolean dfs(WordDictionary wd, String word, int idx){
if(wd == null)
return false;
if(idx == word.length() && wd.isEnd)
return true;
if(idx == word.length())
return false;
char c = word.charAt(idx);
if(c != '.'){
if(wd.next[c - 'a'] == null)
return false;
else
return dfs(wd.next[c - 'a'], word, idx + 1);
}else{
for(int i = 0; i < 26; i++){
if(dfs(wd.next[i], word, idx + 1))
return true;
}
return false;
}
}
}
/**
* Your WordDictionary object will be instantiated and called as such:
* WordDictionary obj = new WordDictionary();
* obj.addWord(word);
* boolean param_2 = obj.search(word);
*/
以上是关于LeetCode 230. 二叉搜索树中第K小的元素 / 476. 数字的补数 / 211. 添加与搜索单词 - 数据结构设计(字典树)的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode 230. 二叉搜索树中第K小的元素 (平衡树)
LeetCode——230. 二叉搜索树中第K小的元素(Java)
LeetCode Java刷题笔记— 230. 二叉搜索树中第K小的元素