Python


  • 17

    Solution 1

    Just turn the clock forwards one minute at a time until you reach a time with the original digits.

    from datetime import *
    
    class Solution(object):
        def nextClosestTime(self, time):
            digits = set(time)
            while True:
                time = (datetime.strptime(time, '%H:%M') + timedelta(minutes=1)).strftime('%H:%M')
                if set(time) <= digits:
                    return time
    

    Solution 2

    Return the smallest time that uses the given digits, just make being larger than the input a priority.

    def nextClosestTime(self, time):
        return min((t <= time, t)
                   for i in range(24 * 60)
                   for t in ['%02d:%02d' % divmod(i, 60)]
                   if set(t) <= set(time))[1]
    

    Golfed:

    def nextClosestTime(self, T):
        return min((t<=T,t)for i in range(1440)for t in['%02d:%02d'%divmod(i,60)]if set(t)<=set(T))[1]

  • 0
    J

    Interesting answer, not easy to do this in Java or C++, they don't have primitive data time class


  • 0
    E

    Yeah I kinda did the same thing in Java and it was pretty messy lol. I ended up just doing 2 nested for loops, one outer going from 0 to 24 and the inner one going from 0 to 60 to simulate all the different clock positions. I kept a set of the unique digits in the input time and made sure every clock position I checked had at least one of the input time's digits. Probably a better way to do it though.


  • 0

    @jack76 agreed. I had the same idea in C++, it is ugly, but we only have 1.5 hours during the contest...
    https://discuss.leetcode.com/topic/104723/simple-brute-force-c-using-std-set


  • 1

    @jack76 I'd say the datetime stuff isn't helping me much. It can easily be done with about as much code without that. I had actually done that earlier, but @awice had already done that before me, so that's why I thought about alternative ways. And I quite like this one, partially because I wanted to showcase that datetime stuff to people who don't know it yet.

    I think the real advantage is Python's great support for sets and strings etc, their iteration and their operators. I don't even want to think about how set(time) would look in Java.


  • 0
    J

    @StefanPochmann said in Python:

    iteration

    Yes, the set operations in Python is really helpful in this problem


  • 0

    Just added a second solution that's quite different.


  • 1

    @StefanPochmann said in Python:

    I don't even want to think about how set(time) would look in Java.

    Actually I just came up with a very nice way to do this in Java. Not a Set object, but a set in the sense of a regular expression character class:
    https://discuss.leetcode.com/topic/105411/short-simple-java


  • 0
    Z

    Whenever I saw such a concise code, I know it's you!


  • 0
    D

    Case by case, quite verbose though

    def nextClosestTime(self, time):
        digits = sorted(set(map(int, [ch for ch in time if ch != ':'])))
        
        idx1 = digits.index(int(time[4]))
        if idx1 != len(digits) -1:
            return time[:4] + str(digits[idx1+1])
        
        idx2 = digits.index(int(time[3]))
        if idx2 != len(digits) - 1 and digits[idx2+1] <= 5:
            return time[:3] + str(digits[idx2+1]) + str(digits[0])
        
        idx3 = digits.index(int(time[1]))
        if idx3 != len(digits) - 1 and int(time[0]) * 10 + digits[idx3+1] <= 24:
            return time[:1] + '{0}:{1}{1}'.format(digits[idx3+1], digits[0])
        
        idx4 = digits.index(int(time[0]))
        if idx4 != len(digits) -1 and digits[idx4+1] <=2:
            return '{0}{1}:{1}{1}'.format(digits[idx4+1], digits[0])
        
        return '{0}{0}:{0}{0}'.format(digits[0])

  • 0

    @derek3 It fails a few cases like "22:44" , returning "24:22" instead of "22:22".


  • 0
    Z

    @StefanPochmann said in Python:

    22:44

    I think "24:22" is correct, the question regards "22:22" as tomorrow's time. So "24:22" should be next closest time.


  • 0

    @zpcore So you think "24:22" is a valid time? Have you ever seen any clock or anything that uses that? Can you please show one? The many 24-hour clocks I've seen all go 23:58 -> 23:59 -> 00:00 -> 00:01.


  • 0
    Z

    @StefanPochmann OMG, you are correct! 24:22 is not valid!


  • 0
    D

    @StefanPochmann said in Python:

    "22:44"

    You are right, I should check 3rd digit only up to 23 as 24 is not a valid hour.


  • 0
    M

    I tried to do Solution 1 in JavaScript. Was wondering if there was a shorter/better way?

    If not, I will have to pick up Python soon...

    Also, does Google really ask questions like this one? >.>

    function nextClosestTime(time) {
      var numberChoices = time.split('').filter(x => Number.isInteger(parseInt(x)));
      var [hr, min] = time.split(':');
      var d = new Date(0, 0, 0, hr, min);
      
      while (true) {
        d.setMinutes(d.getMinutes()+1);
        
        var hrStr = pad0(d.getHours());
        var minStr = pad0(d.getMinutes());
    
        if ((hrStr+minStr).split('').every(x => numberChoices.includes(x)))
          return hrStr+':'+minStr;
      }
    }
    
    function pad0(n) {
      return (n < 10 ? '0' : '') + n;
    }
    

  • 0
    C

    Nice solution! Could you explain the usage of set(time) here?


Log in to reply
 

Looks like your connection to LeetCode Discuss was lost, please wait while we try to reconnect.