👽
Software Engineer Interview Handbook
  • README
  • Behavioral
    • Useful Links
    • Dongze Li
  • Algorithm
    • Segment Tree
    • Array
      • Product Of Array Except Self
      • Merge Strings Alternately
      • Increasing Triplet Subsequence
      • String Compression
      • Greatest Common Divisor Strings
      • Max Product Of Three
      • Find Duplicate Num
      • Valid Palindrome Ii
      • Next Permutation
      • Rearrange Array By Sign
      • Removing Min Max Elements
      • Find Original Array From Doubled
      • Reverse Words Ii
    • Backtracking
      • Letter Combination Phone Number
      • Combination Sum Iii
      • N Queens
      • Permutations
      • Combination Sum
    • Binary Search
      • Koko Eating Bananas
      • Find Peak Element
      • Successful Pairs Of Spells Potions
    • Binary Search Tree
      • Delete Node In BST
      • Validate Bst
      • Range Sum Bst
    • Binary Tree
      • Maximum Depth
      • Leaf Similar Trees
      • Maximum Level Sum
      • Binary Tree Right Side
      • Lowest Common Ancestor
      • Longest Zigzag Path
      • Count Good Nodes
      • Path Sum III
      • Maximum Path Sum
      • Move Zero
      • Diameter Binary Tree
      • Sum Root Leaf Number
      • Traversal
      • Binary Tree Vertical Order
      • Height Tree Removal Queries
      • Count Nodes Avg Subtree
      • Distribute Coins
      • Binary Tree Max Path Sum
    • Bit
      • Min Flips
      • Single Number
      • Pow
      • Find Unique Binary Str
    • BFS
      • Rotten Oranges
      • Nearest Exist From Entrance
      • Minimum Knight Moves
      • Network Delay Time
      • Minimum Height Tree
      • Knight Probability In Board
    • Design
      • LRU Cache
      • Get Random
      • LFU Cache
      • Moving Average
      • Rle Iterator
      • Design Hashmap
    • DFS
      • Reorder Routes Lead City
      • Evaluate Division
      • Keys And Rooms
      • Number Of Provinces
      • Disconnected Path With One Flip
      • Course Schedule Ii
      • Robot Room Cleaner
      • Word Break Ii
      • Number Coins In Tree Nodes
      • Maximum Increasing Cells
      • Number Coins In Tree Nodes
      • Detonate Maximum Bombs
      • Find All Possible Recipes
      • Min Fuel Report Capital
      • Similar String Groups
    • DP
      • Domino And Tromino Tiling
      • House Robber
      • Longest Common Subsequence
      • Trade Stock With Transaction Fee
      • Buy And Sell Stock
      • Longest Non Decreasing Subarray
      • Number Of Good Binary Strings
      • Delete And Earn
      • Minimum Costs Using Train Line
      • Decode Ways
      • Trapping Rain Water
      • Count Fertile Pyramids
      • Minimum Time Finish Race
      • Knapsack
      • Count Unique Char Substrs
      • Count All Valid Pickup
    • Greedy
      • Dota2 Senate
      • Smallest Range Ii
      • Can Place Flowers
      • Meeting Rooms II
      • Guess the word
      • Minimum Replacement
      • Longest Palindrome Two Letter Words
      • Parentheses String Valid
      • Largest Palindromic Num
      • Find Missing Observations
      • Most Profit Assigning Work
    • Hashmap
      • Equal Row Column Pairs
      • Two Strings Close
      • Group Anagrams
      • Detect Squares
    • Heap
      • Maximum Subsequence Score
      • Smallest Number Infinite Set
      • Total Cost Hire Workers
      • Kth Largest Element
      • Meeting Rooms III
      • K Closest Points Origin
      • Merge K Sorted List
      • Top K Frequent Elements
      • Meeting Room III
      • Num Flowers Bloom
      • Find Median From Stream
    • Intervals
      • Non Overlapping Intervals
      • Min Arrows Burst Ballons
    • Linkedlist
      • Reverse Linked List
      • Delete Middle Node
      • Odd Even Linkedlist
      • Palindrome Linkedlist
    • Monotonic Stack
      • Daily Temperatures
      • Online Stock Span
    • Random
      • Random Pick With Weight
      • Random Pick Index
      • Shuffle An Array
    • Recursion
      • Difference Between Two Objs
    • Segment Fenwick
      • Longest Increasing Subsequence II
    • Stack
      • Removing Stars From String
      • Asteroid Collision
      • Evaluate Reverse Polish Notation
      • Building With Ocean View
      • Min Remove Parentheses
      • Basic Calculator Ii
      • Simplify Path
      • Min Add Parentheses
    • Prefix Sum
      • Find The Highest Altitude
      • Find Pivot Index
      • Subarray Sum K
      • Range Addition
    • Sliding Window
      • Max Vowels Substring
      • Max Consecutive Ones III
      • Longest Subarray Deleting Element
      • Minimum Window Substring
      • K Radius Subarray Averages
    • String
      • Valid Word Abbreviations
    • Two Pointers
      • Container With Most Water
      • Max Number K Sum Pairs
      • Is Subsequence
      • Num Substrings Contains Three Char
    • Trie
      • Prefix Tree
      • Search Suggestions System
      • Design File System
    • Union Find
      • Accounts Merge
    • Multithreading
      • Basics
      • Web Crawler
  • System Design
    • Operating System
    • Mocks
      • Design ChatGPT
      • Design Web Crawler
      • Distributed Search
      • News Feed Search
      • Top K / Ad Click Aggregation
      • Design Job Scheduler
      • Distributed Message Queue
      • Google Maps
      • Nearby Friends
      • Proximity Service
      • Metrics monitoring and alert system
      • Design Email
      • Design Gaming Leaderboard
      • Facebook New Feed Live Comments
      • Dog Sitting App
      • Design Chat App (WhatsApp)
      • Design Youtube/Netflix
      • Design Google Doc
      • Design Webhook
      • Validate Instacart Shopper Checkout
      • Design Inventory
      • Design donation app
      • Design Twitter
    • Deep-Dive
      • Back of Envelope
      • Message Queue
      • Redis Sorted Set
      • FAQ
      • Geohash
      • Quadtree
      • Redis Pub/Sub
      • Cassandra DB
      • Collaborative Concurrency Control
      • Websocket / Long Polling / SSE
    • DDIA
      • Chapter 2: Data Models and Query Languages
      • Chapter 5: Replication
      • Chapter 9: Consistency and Consensus
  • OOD
    • Overview
    • Design Parking
  • Company Tags
    • Meta
    • Citadel
      • C++ Fundamentals
      • 面经1
      • Fibonacci
      • Pi
      • Probability
    • DoorDash
      • Similar String Groups
      • Door And Gates
      • Max Job Profit
      • Design File System
      • Count All Valid Pickup
      • Most Profit Assigning Work
      • Swap
      • Binary Tree Max Path Sum
      • Nearest Cities
      • Exployee Free Time
      • Tree Add Removal
    • Lyft
      • Autocomplete
      • Job Scheduler
      • Read4
      • Kvstore
    • Amazon
      • Min Binary Str Val
    • AppLovin
      • TODO
      • Java Basic Questions
    • Google
      • Huffman Tree
      • Unique Elements
    • Instacart
      • Meeting Rooms II
      • Pw
      • Pw2
      • Pw3
      • Expression1
      • Expression2
      • Expression3
      • PW All
      • Expression All
      • Wildcard
      • Free forum tech discussion
    • OpenAI
      • Spreadsheet
      • Iterator
      • Kv Store
    • Rabbit
      • Scheduler
      • SchedulerC++
    • [Microsoft]
      • Min Moves Spread Stones
      • Inorder Successor
      • Largest Palindromic Num
      • Count Unique Char Substrs
      • Reverse Words Ii
      • Find Missing Observations
      • Min Fuel Report Capital
      • Design Hashmap
      • Find Original Array From Doubled
      • Num Flowers Bloom
      • Distribute Coins
      • Find Median From Stream
Powered by GitBook
On this page
  1. Company Tags
  2. Lyft

Job Scheduler

// 上机,Job Scheduler。每一行输入是这样:
// J1:Job号;
// 0023, 24小时制的开始时间 00:23;
// 45:Job需要45分钟。
// 输出Job和对应的Machine No.(!!并且,如果同时有多个machine 空闲,要用编号小的那个!!)
// input
// J1 0023 45
// J2 0025 10
// J3 0100 60

// output
// J1 M1
// J2 M2
// J3 M1

// Qs:
// 1. Any duplicate jobs from input?
// 2. If the previous job end 
// Do we have cases for overnight jobs? where it starts with 23:20 for example and last 50 minutes.
// it's hard to justify the end time with other jobs to figure out which one finished first?

#include <vector>
#include <queue>
#include <string>
#include <iostream>
#include <sstream>

using namespace std;

// Convert to number of minutes since midnight?
int parseTime(const string& timeStr) {
    int hour = stoi(timeStr.substr(0, 2));
    int minute = stoi(timeStr.substr(2, 2));
    return hour * 60 + minute;
}

class Machine {
public:
    Machine(int i) {
        idx = i;
        endTime = 0;
    };

    int idx;
    int endTime;

    string getName() {
        return "M" + to_string(this->idx);
    }

    void debug() {
        cout << getName() << " endTime: " << endTime << endl;
    }
};

class Job {
public:
    Job(string id, string startTime, string duration) {
        jobId = id;
        start = parseTime(startTime);
        end = start + stoi(duration);
    }

    string jobId;
    int start;
    int end;
};

// Intuition, we loop through each job,
// for each job we find if there are any idle machine that can handle it, initially we only have one machine.
// 
// Whenever there is no idle machine, we check if ocupied machine has finished?

// N be the number of machines.
// M be the number of jobs.
// Sorting jobs takes O(M*LogM)
// Popping and pushing into PQ each cost O(logN) with for loop over jobs: O(M*LogN)

// Time: O(mlogm + mlogn), Space: O(n + logn for sort in c++)
unordered_map<string, string> jobScheduler(vector<Job>& jobs) {
    if (jobs.empty()) {
        return {};
    }

    sort(jobs.begin(), jobs.end(), [](const Job& j1, Job& j2) {
        return j1.start < j2.start;
    });

    auto occupiedMachineCmp = [](Machine a, Machine b) {
        if (a.endTime == b.endTime) {
            return a.idx > b.idx;
        }

        return a.endTime > b.endTime;
    };

    auto idleMachineCmp = [](Machine a, Machine b) {
        return a.idx > b.idx;
    };

    priority_queue<Machine, vector<Machine>, decltype(occupiedMachineCmp)> occupiedMachinePQ(occupiedMachineCmp);
    priority_queue<Machine, vector<Machine>, decltype(idleMachineCmp)> idleMachinePQ(idleMachineCmp);

    // The first idle machine.
    Machine m1 = Machine(1);
    idleMachinePQ.push(m1);

    int n = jobs.size();
    int counter = 2; // new machine will start with number 2.
    unordered_map<string, string> assignments;
    for (int i = 0; i < n; i++) {
        string jobId = jobs[i].jobId;
        int jobStartTime = jobs[i].start;
        int jobEndTime = jobs[i].end;

        // if (!occupiedMachinePQ.empty()) {
        //     Machine m = occupiedMachinePQ.top();
        //     m.debug();
        // }
        // cout << "curr job start time: " << jobStartTime << endl;

        // Move machine from occupied machine to idle machine if previous job already ended.
        while (!occupiedMachinePQ.empty() && occupiedMachinePQ.top().endTime <= jobStartTime) {
            Machine curr = occupiedMachinePQ.top();
            occupiedMachinePQ.pop();
            idleMachinePQ.push(curr);
        }

        // If we have idle machine, use it.
        if (idleMachinePQ.size() > 0) {
            Machine curr = idleMachinePQ.top();
            idleMachinePQ.pop();
            curr.endTime = jobEndTime;
            occupiedMachinePQ.push(curr);
            assignments[jobId] = curr.getName();
        } else {
            Machine newMachine = Machine(counter++);
            newMachine.endTime = jobEndTime;
            occupiedMachinePQ.push(newMachine);
            assignments[jobId] = newMachine.getName();
        }
    }

    return assignments;
}

vector<Job> parseStdin() {
    vector<Job> res;

    string line;
    while (getline(cin, line)) {
        string jobId, startTime, endTime;
        istringstream iss(line);
        iss >> jobId >> startTime >> endTime;

        Job j = Job(jobId, startTime, endTime);
        res.push_back(j);
    }

    return res;
}

// J1 0023 45
// J2 0025 10
// J3 0100 60
// J4 0108 20
// J5 0201 30
// J6 0112 30

// job: J4 get assigned to M1
// job : J6 get assigned to M3
// job : J3 get assigned to M2
// job : J2 get assigned to M2
// job : J5 get assigned to M1
// job : J1 get assigned to M1

int main() {
    vector<Job> jobs = parseStdin();
    unordered_map<string, string> res = jobScheduler(jobs);
    for (auto i : res) {
      cout << "job: " << i.first << " get assigned to " << i.second << endl;
    }

    return 0;
}```
PreviousAutocompleteNextRead4

Last updated 1 year ago