【LeetCode - 635】设计日志存储系统

1、题目描述

在这里插入图片描述

2、解题思路

  重新理解一下题意:

  题目给 Put 输入为一个键值对,key 为 id,value 为一个字符串,表示时间戳;

  题目从 Retrieve 获取一个 id,参数 granularity 表示起点从该级往下视为 0,终点从该级往下视为“满”,例如:“2016:01:01:01:01:01” 和 “2017:01:01:23:00:00”,如果 granularity 为 “YEAR” ,则把这两个字符串看成 “2016:00:00:00:00:00” 和 “2017:12:31:23:59:59”。

  题目的难点在于如何根据给定的起点、终点和 granularity 获取 id。

  考虑到字符串比较大小不方便,把时间戳转成一个数字,题目注释说给定的年份是 2000 年到 2017 年,我们可以把时间戳改成从 1999 年开始的秒数。

  例如时间戳为:“2016:01:01:00:00:00”,先转成 int 数组:st = [2016, 1, 1, 0, 0, 0],接着计算出它从 [1999,0,0,0,0,0] 开始的秒数,即:

  (st[0] - 1999L) * (31 * 12) * 24 * 60 * 60 + // 年
  st[1] * 31 * 24 * 60 * 60 + // 月
  st[2] * 24 * 60 * 60 + // 日
  st[3] * 60 * 60 + // 时
  st[4] * 60 + // 分
  st[5]; // 秒

  把时间戳对应的秒数和 id 存储到一个 list 中。

  使用 Retrieve 函数时,计算出 start 对应的秒数和 end+1 对应的秒数,然后从 list 中找到这两个秒数之间的时间戳的 id 即可。

3、解题代码

public class LogSystem {
    // [0] 为时间戳,[1] 为 id
    ArrayList<long[]> list;

    public LogSystem() {
        list = new ArrayList<long[]>();
    }

    /**
     * "2016:01:01:00:00:00" 转为 [2016, 1, 1, 0, 0, 0],再转为秒数,存入 list
     * @param id
     * @param timestamp
     */
    public void put(int id, String timestamp) {
        String[] strs = timestamp.split(":");
        int[] st = new int[strs.length];
        for (int i = 0; i < strs.length; i++) {
            st[i] = Integer.parseInt(strs[i]);
        }
        list.add(new long[]{convert(st), id});
    }

    /**
     * 将时间戳转换为从 1999 年开始到该时间戳的秒数
     *
     * @param st
     * @return
     */
    public long convert(int[] st) {
        st[1] = st[1] - (st[1] == 0 ? 0 : 1);
        st[2] = st[2] - (st[2] == 0 ? 0 : 1);
        return (st[0] - 1999L) * (31 * 12) * 24 * 60 * 60 + // 由于本题中年份的限制在 [2000, 2017] 之间,因此我们可以将时间戳转换为从 1999 年开始到该时间戳的秒数。
                st[1] * 31 * 24 * 60 * 60 + // 将每个月都看成 31 天,这样偏序关系仍然能够保持,只是有些整数没有对应的时间戳而已
                st[2] * 24 * 60 * 60 +  // 日
                st[3] * 60 * 60 + // 时
                st[4] * 60 +   // 分
                st[5];  // 秒
    }

    /**
     * 返回在给定时间区间内的所有日志的 id
     *
     * @param s   start 、 end 和 timestamp 的格式相同
     * @param e
     * @param gra granularity 表示考虑的时间级
     * @return
     */
    public List<Integer> retrieve(String s, String e, String gra) {
        List<Integer> ans = new ArrayList();
        long start = granularity(s, gra, false);
        long end = granularity(e, gra, true);
        for (int i = 0; i < list.size(); i++) {
            // 注意 end 没有等于
            if (list.get(i)[0] >= start && list.get(i)[0] < end)
                ans.add((int) list.get(i)[1]);
        }
        return ans;
    }

    public long granularity(String s, String gra, boolean end) {
        HashMap<String, Integer> h = new HashMap<>();
        h.put("Year", 0);
        h.put("Month", 1);
        h.put("Day", 2);
        h.put("Hour", 3);
        h.put("Minute", 4);
        h.put("Second", 5);
        String[] res = new String[]{"1999", "00", "00", "00", "00", "00"};
        String[] st = s.split(":");
        for (int i = 0; i <= h.get(gra); i++) {
            res[i] = st[i];
        }
        int[] t = new int[res.length];
        for (int i = 0; i < res.length; i++) {
            t[i] = Integer.parseInt(res[i]);
        }
        if (end) {
            t[h.get(gra)]++;
        }
        return convert(t);
    }
}

/**
 * Your LogSystem object will be instantiated and called as such:
 * LogSystem obj = new LogSystem();
 * obj.put(id,timestamp);
 * List<Integer> param_2 = obj.retrieve(s,e,gra);
 */
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
LeetCode-Editor是一种在线编码工具,它提供了一个用户友好的界面编写和运行代码。在使用LeetCode-Editor时,有时候会出现乱码的问。 乱码的原因可能是由于编码格式不兼容或者编码错误导致的。在这种情况下,我们可以尝试以下几种解决方法: 1. 检查文件编码格式:首先,我们可以检查所编辑的文件的编码格式。通常来说,常用的编码格式有UTF-8和ASCII等。我们可以将编码格式更改为正确的格式。在LeetCode-Editor中,可以通过界面设置或编辑器设置来更改编码格式。 2. 使用正确的字符集:如果乱码是由于使用了不同的字符集导致的,我们可以尝试更改使用正确的字符集。常见的字符集如Unicode或者UTF-8等。在LeetCode-Editor中,可以在编辑器中选择正确的字符集。 3. 使用合适的编辑器:有时候,乱码问可能与LeetCode-Editor自身相关。我们可以尝试使用其他编码工具,如Text Editor、Sublime Text或者IDE,看是否能够解决乱码问。 4. 查找特殊字符:如果乱码问只出现在某些特殊字符上,我们可以尝试找到并替换这些字符。通过仔细检查代码,我们可以找到导致乱码的特定字符,并进行修正或替换。 总之,解决LeetCode-Editor乱码问的方法有很多。根据具体情况,我们可以尝试更改文件编码格式、使用正确的字符集、更换编辑器或者查找并替换特殊字符等方法来解决这个问

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值