Intersection of the interval set











up vote
1
down vote

favorite












Recently I had an interview where it was asked:
Given a list of people with their birth and end years find the year with the most number of people alive.
I implemented in Java and was trying to find the optimal solution. I am sure there might be some data structure which will be optimal to use in this scenario.



static class Person {
int born;
int died;

Person(int born, int died) {
this.born = born;
this.died = died;
}
}

/*
* (1920, 1939),
* (1911, 1944),
* (1920, 1955),
* (1938, 1939),
* (1920, 1939),
* (1911, 1944),
* (1920, 1955),
* (1938, 1939),
* (1937, 1940)
*
*/

public static void main(String args) {
List<Person> people = new ArrayList<>();
people.add(new Person(1933, 1989));
people.add(new Person(1920, 1939));
people.add(new Person(1911, 1944));
people.add(new Person(1920, 1955));
people.add(new Person(1938, 1939));
people.add(new Person(1920, 1939));
people.add(new Person(1911, 1944));
people.add(new Person(1920, 1955));
people.add(new Person(1938, 1939));
people.add(new Person(1937, 1940));
System.out.println(solution1(people));

}

public static int solution1(List<Person> people) {
HashMap<Integer, Integer> peopleMap = new HashMap<>();
int maxCount = 0;
int year = 0;
for (Person p : people) {
for (int i = p.born; i <= p.died; i++) {
Integer value = peopleMap.get(i);
if (value == null) {
peopleMap.put(i, 1);
} else {
value++;
if (maxCount < value) {
maxCount = value;
year = i;
}
peopleMap.put(i, value);
}
}
}
return year;
}









share|improve this question
















bumped to the homepage by Community 19 mins ago


This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.



















    up vote
    1
    down vote

    favorite












    Recently I had an interview where it was asked:
    Given a list of people with their birth and end years find the year with the most number of people alive.
    I implemented in Java and was trying to find the optimal solution. I am sure there might be some data structure which will be optimal to use in this scenario.



    static class Person {
    int born;
    int died;

    Person(int born, int died) {
    this.born = born;
    this.died = died;
    }
    }

    /*
    * (1920, 1939),
    * (1911, 1944),
    * (1920, 1955),
    * (1938, 1939),
    * (1920, 1939),
    * (1911, 1944),
    * (1920, 1955),
    * (1938, 1939),
    * (1937, 1940)
    *
    */

    public static void main(String args) {
    List<Person> people = new ArrayList<>();
    people.add(new Person(1933, 1989));
    people.add(new Person(1920, 1939));
    people.add(new Person(1911, 1944));
    people.add(new Person(1920, 1955));
    people.add(new Person(1938, 1939));
    people.add(new Person(1920, 1939));
    people.add(new Person(1911, 1944));
    people.add(new Person(1920, 1955));
    people.add(new Person(1938, 1939));
    people.add(new Person(1937, 1940));
    System.out.println(solution1(people));

    }

    public static int solution1(List<Person> people) {
    HashMap<Integer, Integer> peopleMap = new HashMap<>();
    int maxCount = 0;
    int year = 0;
    for (Person p : people) {
    for (int i = p.born; i <= p.died; i++) {
    Integer value = peopleMap.get(i);
    if (value == null) {
    peopleMap.put(i, 1);
    } else {
    value++;
    if (maxCount < value) {
    maxCount = value;
    year = i;
    }
    peopleMap.put(i, value);
    }
    }
    }
    return year;
    }









    share|improve this question
















    bumped to the homepage by Community 19 mins ago


    This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.

















      up vote
      1
      down vote

      favorite









      up vote
      1
      down vote

      favorite











      Recently I had an interview where it was asked:
      Given a list of people with their birth and end years find the year with the most number of people alive.
      I implemented in Java and was trying to find the optimal solution. I am sure there might be some data structure which will be optimal to use in this scenario.



      static class Person {
      int born;
      int died;

      Person(int born, int died) {
      this.born = born;
      this.died = died;
      }
      }

      /*
      * (1920, 1939),
      * (1911, 1944),
      * (1920, 1955),
      * (1938, 1939),
      * (1920, 1939),
      * (1911, 1944),
      * (1920, 1955),
      * (1938, 1939),
      * (1937, 1940)
      *
      */

      public static void main(String args) {
      List<Person> people = new ArrayList<>();
      people.add(new Person(1933, 1989));
      people.add(new Person(1920, 1939));
      people.add(new Person(1911, 1944));
      people.add(new Person(1920, 1955));
      people.add(new Person(1938, 1939));
      people.add(new Person(1920, 1939));
      people.add(new Person(1911, 1944));
      people.add(new Person(1920, 1955));
      people.add(new Person(1938, 1939));
      people.add(new Person(1937, 1940));
      System.out.println(solution1(people));

      }

      public static int solution1(List<Person> people) {
      HashMap<Integer, Integer> peopleMap = new HashMap<>();
      int maxCount = 0;
      int year = 0;
      for (Person p : people) {
      for (int i = p.born; i <= p.died; i++) {
      Integer value = peopleMap.get(i);
      if (value == null) {
      peopleMap.put(i, 1);
      } else {
      value++;
      if (maxCount < value) {
      maxCount = value;
      year = i;
      }
      peopleMap.put(i, value);
      }
      }
      }
      return year;
      }









      share|improve this question















      Recently I had an interview where it was asked:
      Given a list of people with their birth and end years find the year with the most number of people alive.
      I implemented in Java and was trying to find the optimal solution. I am sure there might be some data structure which will be optimal to use in this scenario.



      static class Person {
      int born;
      int died;

      Person(int born, int died) {
      this.born = born;
      this.died = died;
      }
      }

      /*
      * (1920, 1939),
      * (1911, 1944),
      * (1920, 1955),
      * (1938, 1939),
      * (1920, 1939),
      * (1911, 1944),
      * (1920, 1955),
      * (1938, 1939),
      * (1937, 1940)
      *
      */

      public static void main(String args) {
      List<Person> people = new ArrayList<>();
      people.add(new Person(1933, 1989));
      people.add(new Person(1920, 1939));
      people.add(new Person(1911, 1944));
      people.add(new Person(1920, 1955));
      people.add(new Person(1938, 1939));
      people.add(new Person(1920, 1939));
      people.add(new Person(1911, 1944));
      people.add(new Person(1920, 1955));
      people.add(new Person(1938, 1939));
      people.add(new Person(1937, 1940));
      System.out.println(solution1(people));

      }

      public static int solution1(List<Person> people) {
      HashMap<Integer, Integer> peopleMap = new HashMap<>();
      int maxCount = 0;
      int year = 0;
      for (Person p : people) {
      for (int i = p.born; i <= p.died; i++) {
      Integer value = peopleMap.get(i);
      if (value == null) {
      peopleMap.put(i, 1);
      } else {
      value++;
      if (maxCount < value) {
      maxCount = value;
      year = i;
      }
      peopleMap.put(i, value);
      }
      }
      }
      return year;
      }






      java algorithm interview-questions interval






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Apr 6 at 17:17









      200_success

      127k15148412




      127k15148412










      asked Apr 6 at 15:13









      MrA

      193128




      193128





      bumped to the homepage by Community 19 mins ago


      This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.







      bumped to the homepage by Community 19 mins ago


      This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.
























          2 Answers
          2






          active

          oldest

          votes

















          up vote
          0
          down vote













          HashMap is overkill here.



          Depending on the constraints of the problem (mainly the minimum and maximum allowable years), you could simply use an array instead of a HashMap.



          Sure HashMaps have a O(1) complexity, but nothing is going to beat just indexing an array.



          Better algorithm



          Coming up with a better algorithm is very tricky.



          Your solution is O(NL) where N is the number of people and L is the average lifetime. But keep in mind that L is practically a constant, so it does not really matter that much.



          You could most certainly come up with a O(NlogN) solution, based on creating a sorted list of relevant dates. This would outperform your current solution for small values of N, but better performance at the low end is rarely useful (it can be, but that's the exception, not the rule).



          Edit Thinking about this, I suspect that's the "trick" part of that interview question. Overlapping intervals is a classic interview problem. However, making the intervals happen on a fully discretized space makes the hashmap solution viable, whereas it can't be used when dealing with "traditional" float-bound intervals.






          share|improve this answer























          • The sorted list of dates is probably the best answer. generate a sorted list at logN then iterate over it once keeping a running count. There might be some other tricky way to do it with a single pass and some interesting custom data structure--but I can't see it (and it would probably still be logN to create your Interesting data structure).
            – Bill K
            Apr 6 at 16:24










          • @BillK You'll have a hard time generating the list without visiting each element, making that a NlogN. For reference, the "interesting data structure" could simply be a pair of dates/bool (wether it's a birth or a death).
            – Frank
            Apr 6 at 16:27












          • Yeah, that's what I meant--logN to create it while it's being iterated over would = NlogN... I didn't say that very clearly, thanks :)
            – Bill K
            Apr 6 at 17:43


















          up vote
          0
          down vote













          Nothing wrong with using the HashMap, but…



          … all you actually need to store is the overall change for each year. Not even total births or deaths, just the total change. You can iterate at the end, and (keeping a high water mark) to find the maximum you only need to check when your change for the year is positive.



          Things that might help




          • Sort by birth, and keep a priority queue of deaths.

          • Separate the birth and death, sort both lists.


          Plenty wrong with the question, though



          (the interviewer’s, not your posting here).




          • Should changes be considered to happen at the start of the year?

          • The end?

          • When do you measure?

          • Is it the average number for the year, or the maximum possible? Do any of the births happen before any of the deaths?


          .. and so on. The problem is a little under-specified.






          share|improve this answer





















            Your Answer





            StackExchange.ifUsing("editor", function () {
            return StackExchange.using("mathjaxEditing", function () {
            StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
            StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
            });
            });
            }, "mathjax-editing");

            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "196"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            convertImagesToLinks: false,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f191416%2fintersection-of-the-interval-set%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            2 Answers
            2






            active

            oldest

            votes








            2 Answers
            2






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            0
            down vote













            HashMap is overkill here.



            Depending on the constraints of the problem (mainly the minimum and maximum allowable years), you could simply use an array instead of a HashMap.



            Sure HashMaps have a O(1) complexity, but nothing is going to beat just indexing an array.



            Better algorithm



            Coming up with a better algorithm is very tricky.



            Your solution is O(NL) where N is the number of people and L is the average lifetime. But keep in mind that L is practically a constant, so it does not really matter that much.



            You could most certainly come up with a O(NlogN) solution, based on creating a sorted list of relevant dates. This would outperform your current solution for small values of N, but better performance at the low end is rarely useful (it can be, but that's the exception, not the rule).



            Edit Thinking about this, I suspect that's the "trick" part of that interview question. Overlapping intervals is a classic interview problem. However, making the intervals happen on a fully discretized space makes the hashmap solution viable, whereas it can't be used when dealing with "traditional" float-bound intervals.






            share|improve this answer























            • The sorted list of dates is probably the best answer. generate a sorted list at logN then iterate over it once keeping a running count. There might be some other tricky way to do it with a single pass and some interesting custom data structure--but I can't see it (and it would probably still be logN to create your Interesting data structure).
              – Bill K
              Apr 6 at 16:24










            • @BillK You'll have a hard time generating the list without visiting each element, making that a NlogN. For reference, the "interesting data structure" could simply be a pair of dates/bool (wether it's a birth or a death).
              – Frank
              Apr 6 at 16:27












            • Yeah, that's what I meant--logN to create it while it's being iterated over would = NlogN... I didn't say that very clearly, thanks :)
              – Bill K
              Apr 6 at 17:43















            up vote
            0
            down vote













            HashMap is overkill here.



            Depending on the constraints of the problem (mainly the minimum and maximum allowable years), you could simply use an array instead of a HashMap.



            Sure HashMaps have a O(1) complexity, but nothing is going to beat just indexing an array.



            Better algorithm



            Coming up with a better algorithm is very tricky.



            Your solution is O(NL) where N is the number of people and L is the average lifetime. But keep in mind that L is practically a constant, so it does not really matter that much.



            You could most certainly come up with a O(NlogN) solution, based on creating a sorted list of relevant dates. This would outperform your current solution for small values of N, but better performance at the low end is rarely useful (it can be, but that's the exception, not the rule).



            Edit Thinking about this, I suspect that's the "trick" part of that interview question. Overlapping intervals is a classic interview problem. However, making the intervals happen on a fully discretized space makes the hashmap solution viable, whereas it can't be used when dealing with "traditional" float-bound intervals.






            share|improve this answer























            • The sorted list of dates is probably the best answer. generate a sorted list at logN then iterate over it once keeping a running count. There might be some other tricky way to do it with a single pass and some interesting custom data structure--but I can't see it (and it would probably still be logN to create your Interesting data structure).
              – Bill K
              Apr 6 at 16:24










            • @BillK You'll have a hard time generating the list without visiting each element, making that a NlogN. For reference, the "interesting data structure" could simply be a pair of dates/bool (wether it's a birth or a death).
              – Frank
              Apr 6 at 16:27












            • Yeah, that's what I meant--logN to create it while it's being iterated over would = NlogN... I didn't say that very clearly, thanks :)
              – Bill K
              Apr 6 at 17:43













            up vote
            0
            down vote










            up vote
            0
            down vote









            HashMap is overkill here.



            Depending on the constraints of the problem (mainly the minimum and maximum allowable years), you could simply use an array instead of a HashMap.



            Sure HashMaps have a O(1) complexity, but nothing is going to beat just indexing an array.



            Better algorithm



            Coming up with a better algorithm is very tricky.



            Your solution is O(NL) where N is the number of people and L is the average lifetime. But keep in mind that L is practically a constant, so it does not really matter that much.



            You could most certainly come up with a O(NlogN) solution, based on creating a sorted list of relevant dates. This would outperform your current solution for small values of N, but better performance at the low end is rarely useful (it can be, but that's the exception, not the rule).



            Edit Thinking about this, I suspect that's the "trick" part of that interview question. Overlapping intervals is a classic interview problem. However, making the intervals happen on a fully discretized space makes the hashmap solution viable, whereas it can't be used when dealing with "traditional" float-bound intervals.






            share|improve this answer














            HashMap is overkill here.



            Depending on the constraints of the problem (mainly the minimum and maximum allowable years), you could simply use an array instead of a HashMap.



            Sure HashMaps have a O(1) complexity, but nothing is going to beat just indexing an array.



            Better algorithm



            Coming up with a better algorithm is very tricky.



            Your solution is O(NL) where N is the number of people and L is the average lifetime. But keep in mind that L is practically a constant, so it does not really matter that much.



            You could most certainly come up with a O(NlogN) solution, based on creating a sorted list of relevant dates. This would outperform your current solution for small values of N, but better performance at the low end is rarely useful (it can be, but that's the exception, not the rule).



            Edit Thinking about this, I suspect that's the "trick" part of that interview question. Overlapping intervals is a classic interview problem. However, making the intervals happen on a fully discretized space makes the hashmap solution viable, whereas it can't be used when dealing with "traditional" float-bound intervals.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Apr 6 at 16:32

























            answered Apr 6 at 16:04









            Frank

            3,036321




            3,036321












            • The sorted list of dates is probably the best answer. generate a sorted list at logN then iterate over it once keeping a running count. There might be some other tricky way to do it with a single pass and some interesting custom data structure--but I can't see it (and it would probably still be logN to create your Interesting data structure).
              – Bill K
              Apr 6 at 16:24










            • @BillK You'll have a hard time generating the list without visiting each element, making that a NlogN. For reference, the "interesting data structure" could simply be a pair of dates/bool (wether it's a birth or a death).
              – Frank
              Apr 6 at 16:27












            • Yeah, that's what I meant--logN to create it while it's being iterated over would = NlogN... I didn't say that very clearly, thanks :)
              – Bill K
              Apr 6 at 17:43


















            • The sorted list of dates is probably the best answer. generate a sorted list at logN then iterate over it once keeping a running count. There might be some other tricky way to do it with a single pass and some interesting custom data structure--but I can't see it (and it would probably still be logN to create your Interesting data structure).
              – Bill K
              Apr 6 at 16:24










            • @BillK You'll have a hard time generating the list without visiting each element, making that a NlogN. For reference, the "interesting data structure" could simply be a pair of dates/bool (wether it's a birth or a death).
              – Frank
              Apr 6 at 16:27












            • Yeah, that's what I meant--logN to create it while it's being iterated over would = NlogN... I didn't say that very clearly, thanks :)
              – Bill K
              Apr 6 at 17:43
















            The sorted list of dates is probably the best answer. generate a sorted list at logN then iterate over it once keeping a running count. There might be some other tricky way to do it with a single pass and some interesting custom data structure--but I can't see it (and it would probably still be logN to create your Interesting data structure).
            – Bill K
            Apr 6 at 16:24




            The sorted list of dates is probably the best answer. generate a sorted list at logN then iterate over it once keeping a running count. There might be some other tricky way to do it with a single pass and some interesting custom data structure--but I can't see it (and it would probably still be logN to create your Interesting data structure).
            – Bill K
            Apr 6 at 16:24












            @BillK You'll have a hard time generating the list without visiting each element, making that a NlogN. For reference, the "interesting data structure" could simply be a pair of dates/bool (wether it's a birth or a death).
            – Frank
            Apr 6 at 16:27






            @BillK You'll have a hard time generating the list without visiting each element, making that a NlogN. For reference, the "interesting data structure" could simply be a pair of dates/bool (wether it's a birth or a death).
            – Frank
            Apr 6 at 16:27














            Yeah, that's what I meant--logN to create it while it's being iterated over would = NlogN... I didn't say that very clearly, thanks :)
            – Bill K
            Apr 6 at 17:43




            Yeah, that's what I meant--logN to create it while it's being iterated over would = NlogN... I didn't say that very clearly, thanks :)
            – Bill K
            Apr 6 at 17:43












            up vote
            0
            down vote













            Nothing wrong with using the HashMap, but…



            … all you actually need to store is the overall change for each year. Not even total births or deaths, just the total change. You can iterate at the end, and (keeping a high water mark) to find the maximum you only need to check when your change for the year is positive.



            Things that might help




            • Sort by birth, and keep a priority queue of deaths.

            • Separate the birth and death, sort both lists.


            Plenty wrong with the question, though



            (the interviewer’s, not your posting here).




            • Should changes be considered to happen at the start of the year?

            • The end?

            • When do you measure?

            • Is it the average number for the year, or the maximum possible? Do any of the births happen before any of the deaths?


            .. and so on. The problem is a little under-specified.






            share|improve this answer

























              up vote
              0
              down vote













              Nothing wrong with using the HashMap, but…



              … all you actually need to store is the overall change for each year. Not even total births or deaths, just the total change. You can iterate at the end, and (keeping a high water mark) to find the maximum you only need to check when your change for the year is positive.



              Things that might help




              • Sort by birth, and keep a priority queue of deaths.

              • Separate the birth and death, sort both lists.


              Plenty wrong with the question, though



              (the interviewer’s, not your posting here).




              • Should changes be considered to happen at the start of the year?

              • The end?

              • When do you measure?

              • Is it the average number for the year, or the maximum possible? Do any of the births happen before any of the deaths?


              .. and so on. The problem is a little under-specified.






              share|improve this answer























                up vote
                0
                down vote










                up vote
                0
                down vote









                Nothing wrong with using the HashMap, but…



                … all you actually need to store is the overall change for each year. Not even total births or deaths, just the total change. You can iterate at the end, and (keeping a high water mark) to find the maximum you only need to check when your change for the year is positive.



                Things that might help




                • Sort by birth, and keep a priority queue of deaths.

                • Separate the birth and death, sort both lists.


                Plenty wrong with the question, though



                (the interviewer’s, not your posting here).




                • Should changes be considered to happen at the start of the year?

                • The end?

                • When do you measure?

                • Is it the average number for the year, or the maximum possible? Do any of the births happen before any of the deaths?


                .. and so on. The problem is a little under-specified.






                share|improve this answer












                Nothing wrong with using the HashMap, but…



                … all you actually need to store is the overall change for each year. Not even total births or deaths, just the total change. You can iterate at the end, and (keeping a high water mark) to find the maximum you only need to check when your change for the year is positive.



                Things that might help




                • Sort by birth, and keep a priority queue of deaths.

                • Separate the birth and death, sort both lists.


                Plenty wrong with the question, though



                (the interviewer’s, not your posting here).




                • Should changes be considered to happen at the start of the year?

                • The end?

                • When do you measure?

                • Is it the average number for the year, or the maximum possible? Do any of the births happen before any of the deaths?


                .. and so on. The problem is a little under-specified.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Apr 7 at 0:41









                Will Crawford

                1112




                1112






























                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Code Review Stack Exchange!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    Use MathJax to format equations. MathJax reference.


                    To learn more, see our tips on writing great answers.





                    Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                    Please pay close attention to the following guidance:


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f191416%2fintersection-of-the-interval-set%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    404 Error Contact Form 7 ajax form submitting

                    How to know if a Active Directory user can login interactively

                    Refactoring coordinates for Minecraft Pi buildings written in Python