力扣解法汇总432-全 O(1) 的数据结构

目录链接:

力扣编程题-解法汇总_分享+记录-CSDN博客

GitHub同步刷题项目:

https://github.com/September26/java-algorithms

https://github.com/September26/java-algorithms

原题链接:力扣


描述:

请你设计一个用于存储字符串计数的数据结构,并能够返回计数最小和最大的字符串。

实现 AllOne 类:

AllOne() 初始化数据结构的对象。
inc(String key) 字符串 key 的计数增加 1 。如果数据结构中尚不存在 key ,那么插入计数为 1 的 key 。
dec(String key) 字符串 key 的计数减少 1 。如果 key 的计数在减少后为 0 ,那么需要将这个 key 从数据结构中删除。测试用例保证:在减少计数前,key 存在于数据结构中。
getMaxKey() 返回任意一个计数最大的字符串。如果没有元素存在,返回一个空字符串 "" 。
getMinKey() 返回任意一个计数最小的字符串。如果没有元素存在,返回一个空字符串 "" 。
 

示例:

输入
["AllOne", "inc", "inc", "getMaxKey", "getMinKey", "inc", "getMaxKey", "getMinKey"]
[[], ["hello"], ["hello"], [], [], ["leet"], [], []]
输出
[null, null, null, "hello", "hello", null, "hello", "leet"]

解释
AllOne allOne = new AllOne();
allOne.inc("hello");
allOne.inc("hello");
allOne.getMaxKey(); // 返回 "hello"
allOne.getMinKey(); // 返回 "hello"
allOne.inc("leet");
allOne.getMaxKey(); // 返回 "hello"
allOne.getMinKey(); // 返回 "leet"
 

提示:

1 <= key.length <= 10
key 由小写英文字母组成
测试用例保证:在每次调用 dec 时,数据结构中总存在 key
最多调用 inc、dec、getMaxKey 和 getMinKey 方法 5 * 104 次

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/all-oone-data-structure
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路:

* 解题思路:
* 用两个集合进行数据的存储。
* 第一个集合判断是否含有该元素,第二个集合是按照数量从小到大排列。
* 添加一个字符时,首先判断是否存在该有字符,如果没有则创建Node添加到map当中,并且加入到list的最前面。此时次数为1。
* 如果不为空,则使用需要修改Node的times次数,然后重新排序。
* 删除时逻辑和添加类似。
* 重新排序时,先使用search方法找到该Node节点在list中的位置,然后向后查找,找到其本应该所在的位置,然后交换。
* 我这里的search使用的还是遍历,所以效率比较低。这里使用二叉树查找应该效率会更好一些。

代码:

public class Solution432 {

    public static class AllOne {

        List<Node> list = new ArrayList<>();
        Map<String, Node> indexMap = new HashMap<>();

        public AllOne() {

        }

        public void inc(String key) {
            Node node = indexMap.get(key);
            if (node == null) {
                node = new Node();
                node.key = key;
                node.times = 1;
                list.add(0, node);
                indexMap.put(node.key, node);
                return;
            }
            //二叉树搜索找到node的位置,调整node的位置
            node.times++;
            sort(true, node);
        }

        public void dec(String key) {
            Node node = indexMap.get(key);
            if (node == null) {
                return;
            }
            node.times--;
            if (node.times == 0) {
                indexMap.remove(node.key);
            }
            //重新排序
            sort(false, node);
        }

        public String getMaxKey() {
            if (list.size() == 0) {
                return "";
            }
            return list.get(list.size() - 1).key;
        }

        public String getMinKey() {
            if (list.size() == 0) {
                return "";
            }
            return list.get(0).key;
        }


        private void sort(boolean isForward, Node node) {
            int index = search(node);
            if (node.times == 0) {
                list.remove(index);
                return;
            }
            if (isForward) {
                int i = index + 1;
                for (; i < list.size(); i++) {
                    Node node1 = list.get(i);
                    if (node.times > node1.times) {
                        continue;
                    }
                    break;
                }
                change(node, list.get(i - 1));
                return;
            }
            int i = index - 1;
            for (; i >= 0; i--) {
                Node node1 = list.get(i);
                if (node.times < node1.times) {
                    continue;
                }
                break;
            }
            change(node, list.get(i + 1));
        }

        private int search(Node node) {
            int i = list.indexOf(node);
            return i;
        }

        private void change(Node node, Node node1) {
            if (node.key.equals(node1.key)) {
                return;
            }
            int times = node.times;
            String key = node.key;

            node.times = node1.times;
            node.key = node1.key;

            node1.times = times;
            node1.key = key;
            indexMap.put(node.key, node);
            indexMap.put(node1.key, node1);
        }

        static class Node {
            String key;
            int times;
        }
    }


/**
 * Your AllOne object will be instantiated and called as such:
 * AllOne obj = new AllOne();
 * obj.inc(key);
 * obj.dec(key);
 * String param_3 = obj.getMaxKey();
 * String param_4 = obj.getMinKey();
 */
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

失落夏天

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值