LeetCode157--实现前缀树(L208)、最大正方形(L221)

1、实现前缀树

//Trie(发音类似 “try”)或者说 前缀树 是一种树形数据结构,用于高效地存储和检索字符串数据集中的键。这一数据结构有相当多的应用情景,例如自动补完和拼
//写检查。
//
// 请你实现 Trie 类:
//
//
// Trie() 初始化前缀树对象。
// void insert(String word) 向前缀树中插入字符串 word 。
// boolean search(String word) 如果字符串 word 在前缀树中,返回 true(即,在检索之前已经插入);否则,返回 false
// 。
// boolean startsWith(String prefix) 如果之前已经插入的字符串 word 的前缀之一为 prefix ,返回 true ;否
//则,返回 false 。
//
//
//
//
// 示例:
//
//
//输入
//[“Trie”, “insert”, “search”, “search”, “startsWith”, “insert”, “search”]
//[[], [“apple”], [“apple”], [“app”], [“app”], [“app”], [“app”]]
//输出
//[null, null, true, false, true, null, true]
//
//解释
//Trie trie = new Trie();
//trie.insert(“apple”);
//trie.search(“apple”); // 返回 True
//trie.search(“app”); // 返回 False
//trie.startsWith(“app”); // 返回 True
//trie.insert(“app”);
//trie.search(“app”); // 返回 True
//
//
//
//
// 提示:
//
//
// 1 <= word.length, prefix.length <= 2000
// word 和 prefix 仅由小写英文字母组成
// insert、search 和 startsWith 调用次数 总计 不超过 3 * 104 次
//
// Related Topics 设计 字典树 哈希表 字符串

我们还是以树状结构来对前缀树进行构造,首先每个前缀树节点需要有两个元素:26个子节点以及在该节点处是不是一个单词的结束。据此可以轻松写出成员变量和构造方法:

class Trie {
    //一个节点的子节点,一共可能有26种情况
    private Trie[] children;
    //判断是否已经到了前缀树的末端
    private boolean isEnd;
    /** Initialize your data structure here. */
    public Trie() {
        children = new Trie[26];
        isEnd = false;
    }

其次就是嵌入,嵌入我们采用循环,不断查找下一个字母是否存在于树中,如果不存在,就新建一个子节点,如果存在在最后的那个节点处将其isEnd给设置为true。

public void insert(String word) {
        Trie node = this;
        for (int i = 0; i < word.length(); i++) {
            char c = word.charAt(i);
            int index = c - 'a';
            if(node.children[index] == null){
                node.children[index] = new Trie();
            }
            node = node.children[index];
        }
        node.isEnd = true;
    }

接着就是搜索前缀,其方法和前面的大致一样,不断检查前缀中的字母,如果为空,返回的就是null,如果不为空,查到前缀的最后一个字母并返回该节点。

private Trie searchPrefix(String prefix){
        Trie node = this;
        for (int i = 0; i < prefix.length(); i++) {
            char ch = prefix.charAt(i);
            int index = ch - 'a';
            if(node.children[index] == null){
                return null;
            }
            node = node.children[index];
        }
        return node;
    }

接着就可以判断返回的是不是null,如果是,那么输入的前缀不存在于该前缀树中:

public boolean startsWith(String prefix) {
        if(searchPrefix(prefix) != null){
            return true;
        }
        return false;
    }

最后就是判断单词是不是存在于前缀树中,还是利用查询前缀的方式,但这里不仅要求返回的节点不为null,同时返回的这个节点是单词的结尾节点,即isEnd=true。

public boolean startsWith(String prefix) {
        if(searchPrefix(prefix) != null){
            return true;
        }
        return false;
    }

2、最大的正方形

//在一个由 ‘0’ 和 ‘1’ 组成的二维矩阵内,找到只包含 ‘1’ 的最大正方形,并返回其面积。
//
//
//
// 示例 1:
//
//
//输入:matrix = [[“1”,“0”,“1”,“0”,“0”],[“1”,“0”,“1”,“1”,“1”],[“1”,“1”,“1”,“1”,“1”]
//,[“1”,“0”,“0”,“1”,“0”]]
//输出:4
//
//
// 示例 2:
//
//
//输入:matrix = [[“0”,“1”],[“1”,“0”]]
//输出:1
//
//
// 示例 3:
//
//
//输入:matrix = [[“0”]]
//输出:0
//
//
//
//
// 提示:
//
//
// m == matrix.length
// n == matrix[i].length
// 1 <= m, n <= 300
// matrix[i][j] 为 ‘0’ 或 ‘1’
//
// Related Topics 数组 动态规划 矩阵

public int maximalSquare(char[][] matrix) {
        int m = matrix.length;
        int n = matrix[0].length;
        int[][] ints = new int[m][n];
        for (int i = 0; i < m; i++) {
            ints[i][0] = matrix[i][0] - '0';
        }
        for (int j = 0; j < n; j++) {
            ints[0][j] = matrix[0][j] - '0';
        }
        for (int i = 1; i < m; i++) {
            for (int j = 1; j < n; j++) {
                if(matrix[i][j] == '0'){
                    ints[i][j] = 0;
                }else{
                    if(ints[i-1][j] == 0 || ints[i][j-1] == 0){
                        ints[i][j] = 1;
                    }else if(ints[i-1][j] != ints[i][j-1]){
                        ints[i][j] = Math.min(ints[i-1][j], ints[i][j-1]) + 1;
                    }else{
                        if(ints[i-ints[i-1][j]][j-ints[i-1][j]] != 0){
                            ints[i][j] = ints[i-1][j]+1;
                        }else{
                            ints[i][j] = ints[i-1][j];
                        }
                    }
                }
            }
        }
        int max = 0;
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if(ints[i][j] > max){
                    max = ints[i][j];
                }
            }
        }
        return max*max;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值