Find the year with the most number of people alive in Python

后端 未结 9 2089
梦谈多话
梦谈多话 2020-12-14 20:48

Given a list of people with their birth and end years (all between 1900 and 2000), find the year with the most number of people alive.

Here

相关标签:
9条回答
  • 2020-12-14 21:44

    my answer

    import java.util.LinkedHashMap;
    import java.util.LinkedList;
    import java.util.List;
    import java.util.Map;
    
    public class AlogrimVarsta {
    
        public static void main(String args[]) {
    
            int startYear = 1890;
            int stopYear = 2000;
    
            List<Person> listPerson = new LinkedList<>();
    
            listPerson.add(new Person(1910, 1940));
            listPerson.add(new Person(1920, 1935));
            listPerson.add(new Person(1900, 1950));
            listPerson.add(new Person(1890, 1920));
            listPerson.add(new Person(1890, 2000));
            listPerson.add(new Person(1945, 2000));
    
            Map<Integer, Integer> mapPersoaneCareAuTrait = new LinkedHashMap<>();
    
            for (int x = startYear; x <= stopYear; x++) {
                mapPersoaneCareAuTrait.put(x, 0);
            }
    
            for (int x = startYear; x <= stopYear; x++) {
                for (Person per : listPerson) {
    
                    int value = mapPersoaneCareAuTrait.get(x);
    
                    if (per.getBorn() == x) {
                        mapPersoaneCareAuTrait.put(x, value + 1);
                        continue;
                    }
    
                    if (per.getDie() == x) {
                        mapPersoaneCareAuTrait.put(x, value + 1);
                        continue;
                    }
    
                    if ((per.getDie() - per.getBorn() > per.getDie() - x) && (per.getDie() - x > 0)) {
                        mapPersoaneCareAuTrait.put(x, value + 1);
                        continue;
                    }
    
                }
            }
    
            for (Map.Entry<Integer, Integer> mapEntry : mapPersoaneCareAuTrait.entrySet()) {
                System.out.println("an " + mapEntry.getKey() + " numar " + mapEntry.getValue());            
            }
    
        }
    
        static class Person {
            final private int born;
            final private int die;
    
            public Person(int pBorn, int pDie) {
                die = pDie;
                born = pBorn;
            }
    
            public int getBorn() {
                return born;
            }
    
            public int getDie() {
                return die;
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-14 21:46

    Another solution I just though of:

    • Create 2 tables, birthdates and deathdates.
    • Accumulate birth dates and death dates in those tables.
    • Browse those tables to accumulate the number of alive people at the time.

    Grand total complexity is O(n)

    Implementation

    from collections import Counter
    
    def most_populated(population, single=True):
        birth = map(lambda x: x[0], population)
        death = map(lambda x: x[1] + 1, population)
        b = Counter(birth)
        d = Counter(death)
        alive = 0
        years = {}
        for year in range(min(birth), max(death) + 1):
            alive = alive + b[year] - d[year]
            years[year] = alive
        return max(years, key=years.get) if single else \
               [key for key, val in years.iteritems() if val == max(years.values())]
    

    Better

    from collections import Counter
    from itertools import accumulate
    import operator
    
    def most_populated(population, single=True):
        delta = Counter(x[0] for x in population)
        delta.subtract(Counter(x[1]+1 for x in population))
        start, end = min(delta.keys()), max(delta.keys())
        years = list(accumulate(delta[year] for year in range(start, end)))
        return max(enumerate(years), key=operator.itemgetter(1))[0] + start if single else \
               [i + start for i, val in enumerate(years) if val == max(years)]
    
    0 讨论(0)
  • 2020-12-14 21:47

    How about this one:

    def max_pop(pop):
        p = 0; max = (0,0)
        for y,i in sorted(chain.from_iterable([((b,1), (d+1,-1)) for b,d in pop])):
            p += i
            if p > max[1]: max=(y,p)
        return max
    

    It's not affected by the year span but is nlogn in the |pop| (unless you'd roll out a radix sort which would be ~ 10n for a thousand year span and should be faster for |pop|>1000 ). Can't have both. A very general solution would have to scan first and decide which algo to use based on measured year span and |pop|.

    0 讨论(0)
提交回复
热议问题