Short C++/Java/Python, bit different


  • 40

    Instead of logging print times, I store when it's ok for a message to be printed again. Should be slightly faster, because I don't always have to add or subtract (e.g., timestamp < log[message] + 10) but only do in the true case. Also, it leads to a shorter/simpler longest line of code. Finally, C++ has 0 as default, so I can just use ok[message].


    C++

    class Logger {
    public:
    
        map<string, int> ok;
    
        bool shouldPrintMessage(int timestamp, string message) {
            if (timestamp < ok[message])
                return false;
            ok[message] = timestamp + 10;
            return true;
        }
    };
    

    Python

    class Logger(object):
    
        def __init__(self):
            self.ok = {}
    
        def shouldPrintMessage(self, timestamp, message):
            if timestamp < self.ok.get(message, 0):
                return False
            self.ok[message] = timestamp + 10
            return True
    

    Java

    public class Logger {
    
        private Map<String, Integer> ok = new HashMap<>();
    
        public boolean shouldPrintMessage(int timestamp, String message) {
            if (timestamp < ok.getOrDefault(message, 0))
                return false;
            ok.put(message, timestamp + 10);
            return true;
        }
    }

  • 1
    B

    I think this is the same with
    if (map.containsKey(message) && (timestamp - map.get(message)) < 10) {
    return false;
    }
    map.put(message, timestamp);
    Both are O(1)


  • 2
    Y
    public class Logger {
        private Map<String, Integer> lookup = new HashMap<>();
    
        public boolean shouldPrintMessage(int timestamp, String message) {
            if (lookup.containsKey(message) && (timestamp - lookup.get(message) < 10)) {
                return false;
            } 
            
            lookup.put(message, timestamp);
            
            return true;
        }
    }

  • 0
    Z

    @StefanPochmann six six six


  • 3
    D

    Neat solution, but i was wondering if the space gonna be an issue if we have many different Strings.


  • 2

    @dianhua1560 Eventually it might become a problem, yes. Depends on the circumstances. I guess I could throw out strings last printed more than ten seconds ago. Oh well... could be a follow-up question.


  • 1
    J

    For C++, why using map rather than unordered_map?


  • 2

    @jtee Because "unordered_map" looks ugly.


  • -1
    F

    Although if there are too many different strings, there are some problem(as you have already mentioned), but your solution is soooooooooo awesome man!


  • 0
    R

    Do we need to use ConcurrentHashMap in Java to ensure the synchronization?


  • 0
    R

    @StefanPochmann What a perspective! \m/


  • 0

    brilliant idea!!!


  • 0
    H

    said in Short C++/Java/Python, bit different:

    getOrDefault

    How is it possible to make the message the key? Since it accepts duplicates after 10 seconds and keys should be unique. The uniqueness is not identified here.


  • 0
    This post is deleted!

  • 0

    Can anyone help point out why this solution is wrong? I am really confused. Thanks!

     if(map.containsKey(message)){
                return timestamp - map.get(message) >= 10;
            } 
            map.put(message, timestamp);
            return true;

  • 1
    H

    Your solution is elegant! But for a Logger, probably it not that practical. Since your HashMap soon will blew up ....
    Share my practical solution. Nothing fancy, just keep a window of 10 seconds..

    public class Logger {

    // Algo thinking Queue
    // time = O(N)
    
    class TimeMsg {
        int timestamp;
        String msg;
        public TimeMsg(int timestamp, String msg) {
            this.timestamp = timestamp;
            this.msg = msg;
        }
    }
    
    /** Initialize your data structure here. */
    private static final int MAX_TIME_WINDOW = 10;
    
    Queue<TimeMsg> msgQueue;
    public Logger() {
        msgQueue = new LinkedList<>();
    }
    
    /** Returns true if the message should be printed in the given timestamp, otherwise returns false.
        If this method returns false, the message will not be printed.
        The timestamp is in seconds granularity. */
    public boolean shouldPrintMessage(int timestamp, String message) {
        
        while (!msgQueue.isEmpty() && timestamp - msgQueue.peek().timestamp >= MAX_TIME_WINDOW) {
            msgQueue.poll();
        }
        
        Iterator<TimeMsg> iter = msgQueue.iterator();
        while (iter.hasNext()) {
            TimeMsg tm = iter.next();
            if (tm.msg.equals(message)) return false;
        }
        
        
        msgQueue.offer(new TimeMsg(timestamp, message));
        
        return true;
    }
    

    }


Log in to reply
 

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