Leetcode刷题:2021-07-10每日一题 - 基于时间的键值存储

253 阅读1分钟

这是我参与新手入门的第3篇文章

一、题目描述:

创建一个基于时间的键值存储类 TimeMap,它支持下面两个操作:

  1. set(string key, string value, int timestamp)

存储键 key、值 value,以及给定的时间戳 timestamp。 2. get(string key, int timestamp)

返回先前调用 set(key, value, timestamp_prev) 所存储的值,其中 timestamp_prev <= timestamp。 如果有多个这样的值,则返回对应最大的  timestamp_prev 的那个值。 如果没有值,则返回空字符串("")。

示例 :

输入:inputs = ["TimeMap","set","set","get","get","get","get","get"], inputs = [[],["love","high",10],["love","low",20],["love",5],["love",10],["love",15],["love",20],["love",25]] 输出:[null,null,null,"","high","high","low","low"]  

提示:

  1. 所有的键/值字符串都是小写的。
  2. 所有的键/值字符串长度都在 [1, 100] 范围内。
  3. 所有 TimeMap.set 操作中的时间戳 timestamps 都是严格递增的。
  4. 1 <= timestamp <= 10^7
  5. TimeMap.set 和 TimeMap.get 函数在每个测试用例中将(组合)调用总计 120000 次。

二、思路分析:

实现思路

  • 使用 哈希表 记录 key 对应的数据
  • 提示中提到 set 操作的时间戳 timestamps 是严格递增的, 因此可以使用二分查找

查看题解后发现可以使用 HashMap + TreeMap , 直接调用 TreeMap 的 floorEntry Api 获取结果

遇到的问题

二分查找,边界问题处理

三、AC 代码

哈希表 + 二分查找

    class TimeMap {

    /** Initialize your data structure here. */

    class Node{
        String value;
        int timestamp;

        Node(String value, int timestamp){
            this.value = value;
            this.timestamp = timestamp;
        }
    }

    Map<String, List<Node>> map;
    public TimeMap() {
        map = new HashMap<>();
    }
    
    public void set(String key, String value, int timestamp) {
        Node node = new Node(value, timestamp);
        List<Node> list = map.getOrDefault(key, new ArrayList<>());
        list.add(node);
        map.put(key, list);
    }
    
    public String get(String key, int timestamp) {
        List<Node> list = map.get(key);
        if(list == null || list.size() == 0){
            return "";
        }
        int left = 0;
        int right = list.size() -1 ;
        int mid = 0;
        while(left < right){
            mid = left + right + 1 >> 1;

            if(list.get(mid).timestamp <= timestamp){
                left = mid ;
            }else{
                right = mid - 1;
            }
        }
        Node ans = list.get(right);
        return ans.timestamp <= timestamp ? ans.value : "";
    }
}

哈希表 + TreeMap

class TimeMap {

    /** Initialize your data structure here. */

    class Node{
        String value;
        int timestamp;

        Node(String value, int timestamp){
            this.value = value;
            this.timestamp = timestamp;
        }
    }

    Map<String, TreeMap<Integer, Node>> map;

    public TimeMap() {
        map = new HashMap<>();
    }
    
    public void set(String key, String value, int timestamp) {
        Node node = new Node(value, timestamp);
        TreeMap<Integer, Node> treeMap = map.getOrDefault(key, new TreeMap<>());
        treeMap.put(timestamp, node);
        map.put(key,treeMap);

    }
    
    public String get(String key, int timestamp) {
        TreeMap<Integer, Node> treeMap = map.getOrDefault(key, new TreeMap<>());

        Map.Entry<Integer, Node> entry = treeMap.floorEntry(timestamp);
        if(entry == null){
            return "";
        }

        Node ans = entry.getValue();
        return ans.timestamp <= timestamp ? ans.value : "";
    }
}