Likou Solution Summary 432 - All O(1) Data Structure

Directory link:

Likou Programming Questions - Solution Summary - Sharing + Recording - CSDN Blog

GitHub synchronous brushing project:

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

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

Original title link: force buckle


describe:

Please design a data structure that stores counts of strings and can return the strings with the smallest and largest counts.

Implement the AllOne class:

AllOne() initializes the object of the data structure.
inc(String key) Increments the count of the string key by 1. If the key does not already exist in the data structure, insert a key with a count of 1.
dec(String key) Decrements the count of the string key by 1. If the count for a key is 0 after decrementing, then the key needs to be removed from the data structure. The test case guarantees that the key exists in the data structure before decrementing the count.
getMaxKey() returns any string with the largest count. Returns an empty string "" if no element exists.
getMinKey() returns any string with the smallest count. Returns an empty string "" if no element exists.
 

Example:

输入
["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"
 

hint:

1 <= key.length <= 10
The key is composed of lowercase English letters.
Test case guarantee: every time dec is called, there is always a key in the data structure. The
inc, dec, getMaxKey and getMinKey methods are called at most 5 * 104 times

Source: LeetCode
Link: https://leetcode-cn.com/problems/all-oone-data-structure The
copyright belongs to LeetCode. For commercial reprints, please contact the official authorization, and for non-commercial reprints, please indicate the source.

Problem solving ideas:

* Problem-solving ideas: 
* Use two sets for data storage. 
* The first set determines whether it contains the element, and the second set is arranged according to the number from small to large. 
* When adding a character, first determine whether the character exists, if not, create a Node and add it to the map, and add it to the front of the list. The number of times is 1 at this time. 
* If it is not empty, use the times times that Node needs to be modified, and then reorder. 
* The logic of deletion is similar to that of adding. 
* When reordering, first use the search method to find the position of the Node node in the list, then search backwards, find the position where it should be, and then exchange. 
* My search here still uses traversal, so the efficiency is relatively low. It should be more efficient to use a binary tree search here.

Code:

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();
 */
}

Guess you like

Origin blog.csdn.net/AA5279AA/article/details/123526062