Marathon - Bloomberg


bloomberg 马拉松设计题
第一个问题问的设计题,一个track上有很多runner,还有很多sensor,sensor可以检测到那个runner跑过了这个sensor
用这个系统生成一个dashboard显示runner现在的名次。

先看题,假设一共有n个runner,m个sensor,runner跑的时候经过连续的sensor(不会从sensor1直接到sensor3),而我们需要实现的方法有update(i, j),即runner i 刚刚经过 sensor j;以及getRank(k)获得当下前 k 个选手的名次。

solution 1:
1. 用一个2D array(int[][] ranking , m * n)记录runner跑到哪了,以及一个长 m 的array(int[] counter)记录已有多少个runner经过当前sensor。
2. 每次update(i,j),ranking[j-1][i] = 0, ranking[j][i] = counter[i]+1;
3. 每次getRank(k),从下往上遍历每个sensor,还需将每一行根据ranking[][]的大小排序,拿出前k个。

这用做也许在m,n都比较小的时候可以,但随着m,n增多很不方便。
主要问题是,如何保持每个sensor所“拥有”的runner有先后顺序(如queue),在先后顺序的前提下如何快速删除其中某一个runner(突然跑快了),并append到下一个sensor的队列中;为了取前k个runner,当sensor较多runner比较稀疏时,如何取了一部分后知道下一个有runner的sensor是谁。

solution 2:基于double linked list, hashmap
1. 建立一个HashMap<Runner, Node>, 每个runner对应一个node,O(1)时间找到这个此runner的位置
2. 每个sensor都建立double linked list,O(1)时间删除,且始终有序。删除后加入更新的sensor链尾即可,update时间O(1)
3. 建立另一个长 k 的 double linked list,每个node代表一个sensor,将稀疏的sensor连起来
4. getRank(k)时,依次将每个sensor node中选手按许倒出即可,O(k)



今天刚面到zhe这道题,超水平发挥了。基本上需要实现两个函数 passMilestone(runner), 以及printLeadBoard()打印出所有名次排名,
数据结构用一个hash table和一个doubly linked list,Node 包含runner id, 最后一个经过的milestone id, 经过milestone时候的rank,也就是第几个经过这个打卡点的,还有pre,next指针。注意passMilestone参数只有runner,没有打卡点id,所以hash table的key是runner id,值包含milestone id和rank,每次这个函数调用时候update milestone = milestone + 1,然后查看这个milestone之前几个人经过了得到rank。然后要把自己从doubly linked list中删除,然后找到正确的位置插入。诀窍在于只需要找到和自己milestone id,对每个milestone记住第一个经过的人,这样就可以把自己插入到第一个人之前。时间复杂度O(1)。print时间复杂度O(n)。希望可以帮助到大家。

我当时读到的时候感觉是是笔误。应该是最后一个经过milestone的人。(即加入尾部)
抱歉 馬拉松沒繞圈  沒有這幾個問題

Topk的部分讀起來感覺像:
前k個sensor的最晚離開那位person

你的code中self.sensorHead裡面的index是代表sensors的編號 如果k>nums_of_sensor感覺會Error 如果不會error感覺也沒辦法解決如果第一名第二次經過sensor的問題  這樣跑第二快的選手會變成第一個因為第一名的選手會在一號sensor的最後面(你的addNode()是從list後端加入)

歡迎討論啊有錯誤請指正  這題解決會幫到很多人 一起來幫忙各位兄弟



class LinkedList():
    def __init__(self, person):
        self.person = person
        self.next = None
        self.prev = None
 
class Marrathon():
    def __init__(self, numSensor):
        self.sensorsHead = [0] * numSensor
        self.sensorsTail = [0] * numSensor
        self.person2Node = dict()
        for i in range(numSensor):
            self.head = LinkedList(-1)
            self.tail = LinkedList(-1)
            self.head.next = self.tail
            self.tail.prev = self.head
            self.sensorsHead[i] = self.head
            self.sensorsTail[i] = self.tail
             
    def update(self, person, sensor):
        if person in self.person2Node:
            node = self.person2Node[person]
            self.removeNode(node)
            self.addNode(sensor, node)
        else: # person 1st time appear
            node = LinkedList(person)
            self.person2Node[person] = node
            self.addNode(sensor, node)
         
    def addNode(self, sensor, node):
        tail = self.sensorsTail[sensor]
        p = tail.prev
        p.next = node
        node.next = tail
        tail.prev = node
        node.prev = p
         
    def removeNode(self, node):
        p, n = node.prev, node.next
        p.next = n
        n.prev = p
         
    def topK(self, k):
        res = []
 
        for i in range(len(self.sensorsHead) - 1, -1, -1):
            if k == 0:
                break
            candidate = self.sensorsHead[i].next
            while candidate.person != -1 and k > 0:
                res.append(candidate.person)
                k -= 1
                candidate = candidate.next
        return res

写个我自己的思考,还请大神指点一下

1. sensor/check_pointer那用一个list记录当前sensor有多少个runners;并且有个hashmap记录每个runner_id 和 runner_list的iterator
2. sensor 写一个deleteRunner() ;根据提供的runnerid把当前list和hashmap上的runner_id删除 //  这个runner已经从这个sensor到了另外一个
3. MarathonBoard 的 update( runner_id, sensor_id ) 主要有2步
  3.1) 先根据runner_id 从他之前sensor list里删除
  3.2)再把这个runner_id 放到现在这个sensor_id 里的runner_list 后面去  // 假设每个新的runner都是在这个sensor的runner_list的最后

4. 最后打印top K, 假设sensor都是按先后顺序排好的(如果不是,可以把list改成multiset然后写个compartor),直接把每个sensor上的runner都打印出来就是的了







class Sensor
{
    int s_id;
    int s_distance;
    list<int> runner_list;   // a list of runner_id at this sensor/check_pointer
    unordered_map<int, list<int>::iterator> runner_m_sensor;    // {runner_id : list<runner_id>::iterator}
public:
    Sensor(int id, int dist):s_id(id), s_distance(dist){ }

    void deleteRunner(int runner_id){
        auto it = runner_m_sensor.find(runner_id);
        if (it == runner_m_sensor.end()) return;

        runner_list.erase( runner_m_sensor[runner_id] );
        runner_m_sensor.erase(runner_id);
    }
};

class MarathonBoard{
    list<Sensor> sensor_list;

    unordered_map<int, list<Sensor>::iterator> sensor_m; // {sensor_id: sensor_list::iterator}
    unordered_map<int, int> runner_m;   // {runner_id: sensor_id}

public:
    MarathonBoard(){}
    void update(int runner_id, int sensor_id){
        // 1. delete the runner from his/her previous sensor's runner list       
        int old_sensor_id = runner_m[runner_id];
        auto old_sensor_it = sensor_m[old_sensor_id];
        // delete it from previous runner list
        old_sensor_it->deleteRunner(runner_id);

        // 2. push_back(runner_id) at current sensor's runner list
        // update it to current sensor
        sensor_m[sensor_id]->runner_list.push_back(runner_id);
    }

    void printTopK(int k){
        for (auto &s : sensor_list)
        {
            for (auto &r : s.runner_list)
            {
                if (k >= 0)
                    cout << "Runner id: " << r << endl;
                k--;
            }
        }
    }
};

Labels

LeetCode (1432) GeeksforGeeks (1122) LeetCode - Review (1067) Review (882) Algorithm (668) to-do (609) Classic Algorithm (270) Google Interview (237) Classic Interview (222) Dynamic Programming (220) DP (186) Bit Algorithms (145) POJ (141) Math (137) Tree (132) LeetCode - Phone (129) EPI (122) Cracking Coding Interview (119) DFS (115) Difficult Algorithm (115) Lintcode (115) Different Solutions (110) Smart Algorithm (104) Binary Search (96) BFS (91) HackerRank (90) Binary Tree (86) Hard (79) Two Pointers (78) Stack (76) Company-Facebook (75) BST (72) Graph Algorithm (72) Time Complexity (69) Greedy Algorithm (68) Interval (63) Company - Google (62) Geometry Algorithm (61) Interview Corner (61) LeetCode - Extended (61) Union-Find (60) Trie (58) Advanced Data Structure (56) List (56) Priority Queue (53) Codility (52) ComProGuide (50) LeetCode Hard (50) Matrix (50) Bisection (48) Segment Tree (48) Sliding Window (48) USACO (46) Space Optimization (45) Company-Airbnb (41) Greedy (41) Mathematical Algorithm (41) Tree - Post-Order (41) ACM-ICPC (40) Algorithm Interview (40) Data Structure Design (40) Graph (40) Backtracking (39) Data Structure (39) Jobdu (39) Random (39) Codeforces (38) Knapsack (38) LeetCode - DP (38) Recursive Algorithm (38) String Algorithm (38) TopCoder (38) Sort (37) Introduction to Algorithms (36) Pre-Sort (36) Beauty of Programming (35) Must Known (34) Binary Search Tree (33) Follow Up (33) prismoskills (33) Palindrome (32) Permutation (31) Array (30) Google Code Jam (30) HDU (30) Array O(N) (29) Logic Thinking (29) Monotonic Stack (29) Puzzles (29) Code - Detail (27) Company-Zenefits (27) Microsoft 100 - July (27) Queue (27) Binary Indexed Trees (26) TreeMap (26) to-do-must (26) 1point3acres (25) GeeksQuiz (25) Merge Sort (25) Reverse Thinking (25) hihocoder (25) Company - LinkedIn (24) Hash (24) High Frequency (24) Summary (24) Divide and Conquer (23) Proof (23) Game Theory (22) Topological Sort (22) Lintcode - Review (21) Tree - Modification (21) Algorithm Game (20) CareerCup (20) Company - Twitter (20) DFS + Review (20) DP - Relation (20) Brain Teaser (19) DP - Tree (19) Left and Right Array (19) O(N) (19) Sweep Line (19) UVA (19) DP - Bit Masking (18) LeetCode - Thinking (18) KMP (17) LeetCode - TODO (17) Probabilities (17) Simulation (17) String Search (17) Codercareer (16) Company-Uber (16) Iterator (16) Number (16) O(1) Space (16) Shortest Path (16) itint5 (16) DFS+Cache (15) Dijkstra (15) Euclidean GCD (15) Heap (15) LeetCode - Hard (15) Majority (15) Number Theory (15) Rolling Hash (15) Tree Traversal (15) Brute Force (14) Bucket Sort (14) DP - Knapsack (14) DP - Probability (14) Difficult (14) Fast Power Algorithm (14) Pattern (14) Prefix Sum (14) TreeSet (14) Algorithm Videos (13) Amazon Interview (13) Basic Algorithm (13) Codechef (13) Combination (13) Computational Geometry (13) DP - Digit (13) LCA (13) LeetCode - DFS (13) Linked List (13) Long Increasing Sequence(LIS) (13) Math-Divisible (13) Reservoir Sampling (13) mitbbs (13) Algorithm - How To (12) Company - Microsoft (12) DP - Interval (12) DP - Multiple Relation (12) DP - Relation Optimization (12) LeetCode - Classic (12) Level Order Traversal (12) Prime (12) Pruning (12) Reconstruct Tree (12) Thinking (12) X Sum (12) AOJ (11) Bit Mask (11) Company-Snapchat (11) DP - Space Optimization (11) Dequeue (11) Graph DFS (11) MinMax (11) Miscs (11) Princeton (11) Quick Sort (11) Stack - Tree (11) 尺取法 (11) 挑战程序设计竞赛 (11) Coin Change (10) DFS+Backtracking (10) Facebook Hacker Cup (10) Fast Slow Pointers (10) HackerRank Easy (10) Interval Tree (10) Limited Range (10) Matrix - Traverse (10) Monotone Queue (10) SPOJ (10) Starting Point (10) States (10) Stock (10) Theory (10) Tutorialhorizon (10) Kadane - Extended (9) Mathblog (9) Max-Min Flow (9) Maze (9) Median (9) O(32N) (9) Quick Select (9) Stack Overflow (9) System Design (9) Tree - Conversion (9) Use XOR (9) Book Notes (8) Company-Amazon (8) DFS+BFS (8) DP - States (8) Expression (8) Longest Common Subsequence(LCS) (8) One Pass (8) Quadtrees (8) Traversal Once (8) Trie - Suffix (8) 穷竭搜索 (8) Algorithm Problem List (7) All Sub (7) Catalan Number (7) Cycle (7) DP - Cases (7) Facebook Interview (7) Fibonacci Numbers (7) Flood fill (7) Game Nim (7) Graph BFS (7) HackerRank Difficult (7) Hackerearth (7) Inversion (7) Kadane’s Algorithm (7) Manacher (7) Morris Traversal (7) Multiple Data Structures (7) Normalized Key (7) O(XN) (7) Radix Sort (7) Recursion (7) Sampling (7) Suffix Array (7) Tech-Queries (7) Tree - Serialization (7) Tree DP (7) Trie - Bit (7) 蓝桥杯 (7) Algorithm - Brain Teaser (6) BFS - Priority Queue (6) BFS - Unusual (6) Classic Data Structure Impl (6) DP - 2D (6) DP - Monotone Queue (6) DP - Unusual (6) DP-Space Optimization (6) Dutch Flag (6) How To (6) Interviewstreet (6) Knapsack - MultiplePack (6) Local MinMax (6) MST (6) Minimum Spanning Tree (6) Number - Reach (6) Parentheses (6) Pre-Sum (6) Probability (6) Programming Pearls (6) Rabin-Karp (6) Reverse (6) Scan from right (6) Schedule (6) Stream (6) Subset Sum (6) TSP (6) Xpost (6) n00tc0d3r (6) reddit (6) AI (5) Abbreviation (5) Anagram (5) Art Of Programming-July (5) Assumption (5) Bellman Ford (5) Big Data (5) Code - Solid (5) Code Kata (5) Codility-lessons (5) Coding (5) Company - WMware (5) Convex Hull (5) Crazyforcode (5) DFS - Multiple (5) DFS+DP (5) DP - Multi-Dimension (5) DP-Multiple Relation (5) Eulerian Cycle (5) Graph - Unusual (5) Graph Cycle (5) Hash Strategy (5) Immutability (5) Java (5) LogN (5) Manhattan Distance (5) Matrix Chain Multiplication (5) N Queens (5) Pre-Sort: Index (5) Quick Partition (5) Quora (5) Randomized Algorithms (5) Resources (5) Robot (5) SPFA(Shortest Path Faster Algorithm) (5) Shuffle (5) Sieve of Eratosthenes (5) Strongly Connected Components (5) Subarray Sum (5) Sudoku (5) Suffix Tree (5) Swap (5) Threaded (5) Tree - Creation (5) Warshall Floyd (5) Word Search (5) jiuzhang (5)

Popular Posts