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);
 */
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值