LeetCode681. Next Closest Time

寻找下一个最近的时间
本文介绍了一种算法,用于找出在给定时间之后下一个最接近的有效时间,该有效时间仅包含给定时间中存在的数字。提供了两种解决方案:一种是通过逐分钟模拟来确定答案,另一种则是通过生成所有可能的组合并从中选择合适的小时和分钟。

Solution1

Using the total minute as a expression of the time. Simulate the clock by moving time 1 minute a time. Each time it’s moving forward, if all the digits are allowed, then this is the answer.

Considering we are guarenteed to have a valid time with in the next 24 * 60 = 1440 minute, this is constant time solution.

And the nature way to represent a valid time is always an integer t in the range 0<=t<1440. And the hour is t / 60, the minute is t % 60. And each digit of the hour can be found by hour/10, hour%10, minute/10, minute%10.

class Solution {
    public String nextClosestTime(String time) {
        int cur = Integer.parseInt(time.substring(0, 2)) * 60;
        cur += Integer.parseInt(time.substring(3));

        Set<Integer> allowed = new HashSet<>();
        for (char c : time.toCharArray()) {
            if (c != ':') {
                allowed.add(c - '0');
            }
        }

        while (true) {
            cur = (cur + 1) % (24 * 60);
            int[] digits = new int[]{cur / 60 / 10, cur / 60 % 10, cur % 60 / 10, cur % 60 % 10};
            int count = 0;
            for (int i : digits) {
                if (!allowed.contains(i)) {
                    break;
                }
                count++;
            }

            if (count == 4) {
                return String.format("%02d:%02d", cur / 60, cur % 60);
            }
        }
    }
}

Solution2

Java constnat time, constant space solution. But a little verbose.

For this question, we basically have to consider 2 parts of the time: the hour and the minute.

Thus we first gather all of the numbers and generate all of the possible combinations. This is guaranteed to use at most O(16) space since there is at most 16 unique combinations of numbers.

Then we first try to get a greater minute. If a valid minute cannot be got, we try to get a greater hour. And if a valid hour cannot be got, the solution is simple, just repeat the minimum value we get as both minute and hour.

Since we only checked all of the combinations twice, this is at most O(16 * 2) time.

class Solution {
    // Since we "may assume the given input string is always valid"
    // we can safely write the function without doing extra input checking.
    public String nextClosestTime(String time) {
        String[] input = time.split(":");
        HashSet<Integer> set = new HashSet<Integer>() {{
            add(Integer.parseInt(input[0].substring(0, 1)));
            add(Integer.parseInt(input[0].substring(1, 2)));
            add(Integer.parseInt(input[1].substring(0, 1)));
            add(Integer.parseInt(input[1].substring(1, 2)));
        }};

        // Generate all possible combinations.
        HashSet<Integer> possible = new HashSet<Integer>();
        int minValue = Integer.MAX_VALUE;
        for (int i : set) {
            for (int j : set) {
                int tmp = i * 10 + j;
                possible.add(tmp);
                minValue = Math.min(minValue, tmp);
            }
        }

        String minTime;
        if (minValue < 10) {
            minTime = "0" + String.valueOf(minValue);
        } else {
            minTime = String.valueOf(minValue);
        }

        String ret = "";
        int currMinute = Integer.parseInt(input[1]);
        int currHour = Integer.parseInt(input[0]);
        if (currMinute < 59) {
            int tmpMin = Integer.MAX_VALUE;
            for (int i : possible) {
                if (i > currMinute && i < 60) {
                    tmpMin = Math.min(tmpMin, i);
                }
            }
            if (tmpMin != Integer.MAX_VALUE) {
                if (tmpMin < 10) {
                    ret = ret + input[0] + ":0" + String.valueOf(tmpMin);
                } else {
                    ret = ret + input[0] + ":" + String.valueOf(tmpMin);
                }
                return ret;
            }
        }

        if (currHour < 23) {
            int tmpMin = Integer.MAX_VALUE;
            for (int i : possible) {
                if (i > currHour && i < 24) {
                    tmpMin = Math.min(tmpMin, i);
                }
            }

            if (tmpMin != Integer.MAX_VALUE) {
                if (tmpMin < 10) {
                    ret = ret + "0" + String.valueOf(tmpMin) + ":" + minTime;
                } else {
                    ret = ret + String.valueOf(tmpMin) + ":" + minTime;
                }

                return ret;
            }
        }

        ret = ret + minTime + ":" + minTime;

        return ret;
    }
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

耀凯考前突击大师

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

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

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

打赏作者

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

抵扣说明:

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

余额充值