Open In App

Job Sequencing Problem

Last Updated : 28 Mar, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Given two arrays: deadline[] and profit[], where the index of deadline[] represents a job ID, and deadline[i] denotes the deadline for that job and profit[i] represents profit of doing ith job. Each job takes exactly one unit of time to complete, and only one job can be scheduled at a time. A job earns its corresponding profit only if it is completed within its deadline.

The objective is to determine:

  1. The maximum profit that can be obtained by scheduling the jobs optimally.
  2. The total number of jobs completed to achieve this maximum profit.

Examples: 

Input: deadline[] = [4, 1, 1, 1], profit[] = [20, 10, 40, 30]
Output: 2 60
Explanation: We select 1st and 3rd jobs. All jobs except first job have a deadline of 1, thus only one of these can be selected along with the first job with the total profit gain of 20 + 40 = 60.

Input: deadline[] = [2, 1, 2, 1, 1], profit[] = [100, 19, 27, 25, 15]
Output: 2 127
Explanation: The first and third job have a deadline of 2, thus both of them can be completed and other jobs have a deadline of 1, thus any one of them can be completed. Both the jobs with a deadline of 2 is having the maximum associated profit, so these two will be completed, with the total profit gain of 100 + 27 = 127.

[Naive Approach] Greedy Approach and Sorting - O(n ^ 2) Time and O(n) Space

Step by Step implementation:

  • Store jobs as pairs of (Profit, Deadline): Since we need to prioritize jobs with higher profits, we pair the profit and deadline together.
  • Sort Jobs Based on Profit: We sort the jobs array in descending order of profit so that we prioritize scheduling the most profitable jobs first.
  • Create a Slot Array: We create a slot[] array of size n (equal to the number of jobs) initialized with zeroes. This array will help track which time slots are occupied.
  • Iterate Over Each Job and Try to Schedule It:
    • For each job, check if it can be placed in an available time slot.
    • The job should be scheduled as late as possible but before its deadline.
    • If an empty slot is found, schedule the job there, increment the job count, and add its profit to the total.
    • After processing all jobs, return the number of jobs completed and the total profit earned.
C++
// C++ program to solve job sequencing
// problem with maximu profit
#include<bits/stdc++.h>
using namespace std;

vector<int> jobSequencing(vector<int> &deadline,
                           vector<int> &profit) {
    int n = deadline.size();
    
    // total job count which is done
    int cnt = 0;
    
    // total profit earned
    int totProfit = 0;

    // pair the profit and deadline of
    // all the jos together
    vector<pair<int, int>> jobs;
    for (int i = 0; i < n; i++) {
        jobs.push_back({profit[i], deadline[i]});
    }

    // sort the jobs based on profit
    // in decreasing order
    sort(jobs.begin(), jobs.end(), 
                greater<pair<int, int>>());

    // array to check time slot for job
    vector<int> slot(n, 0);
    for (int i = 0; i < n; i++) {
        int start = min(n, jobs[i].second) - 1;
        for (int j = start; j >= 0; j--) {

            // if slot is empty
            if (slot[j] == 0) {
                slot[j] = 1;
                cnt++;
                totProfit+= jobs[i].first;
                break;
            }
        }
    }
    
    return {cnt, totProfit};
}

int main() {
    vector<int> deadline = {2, 1, 2, 1, 1};
    vector<int> profit = {100, 19, 27, 25, 15};
    vector<int> ans = jobSequencing(deadline, profit);
    cout<<ans[0]<<" "<<ans[1];
    return 0;
}
Java
// Java program to solve job sequencing
// problem with maximum profit

import java.util.*;

class GfG {
     static
    ArrayList<Integer> jobSequencing(int[] deadline, int[] profit) {
        int n = deadline.length;

        // total job count which is done
        int cnt = 0;

        // total profit earned
        int totProfit = 0;

        // pair the profit and deadline of all the jobs together
        ArrayList<int[]> jobs = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            jobs.add(new int[]{profit[i], deadline[i]});
        }

        // sort the jobs based on profit in decreasing order
        jobs.sort((a, b) -> Integer.compare(b[0], a[0]));

        // array to check time slot for job
        int[] slot = new int[n];

        for (int i = 0; i < n; i++) {
            int start = Math.min(n, jobs.get(i)[1]) - 1;
            for (int j = start; j >= 0; j--) {

                // if slot is empty
                if (slot[j] == 0) {
                    slot[j] = 1;
                    cnt++;
                    totProfit += jobs.get(i)[0];
                    break;
                }
            }
        }

        ArrayList<Integer> result = new ArrayList<>();
        result.add(cnt);
        result.add(totProfit);
        return result;
    }

    public static void main(String[] args) {
        int[] deadline = {2, 1, 2, 1, 1};
        int[] profit = {100, 19, 27, 25, 15};

        ArrayList<Integer> ans = jobSequencing(deadline, profit);
        System.out.println(ans.get(0) + " " + ans.get(1));
    }
}
Python
# Pyhton program to solve job sequencing
# problem with maximu profit

def jobSequencing(deadline, profit):
    n = len(deadline)
    
    # total job count which is done
    cnt = 0
    
    # total profit earned
    totProfit = 0

    # pair the profit and deadline of
    # all the jos together and sort it in decreasing order 
    jobs = sorted(zip(profit, deadline), reverse=True)

    # array to check time slot for job
    slot = [0] * n
    for i in range(n):
        start = min(n, jobs[i][1]) - 1
        for j in range(start, -1, -1):

            # if slot is empty
            if slot[j] == 0:
                slot[j] = 1
                cnt += 1
                totProfit += jobs[i][0]
                break
    
    return [cnt, totProfit]


if __name__ == "__main__":
    deadline = [2, 1, 2, 1, 1]
    profit = [100, 19, 27, 25, 15]
    ans = jobSequencing(deadline, profit)
    print(ans[0], ans[1])
C#
// C# program to solve job sequencing
// problem with maximu profit

using System;
using System.Collections.Generic;

class GfG
{
    public static List<int> JobSequencing(int[] deadline, int[] profit)
    {
        int n = deadline.Length;
        
        // total job count which is done
        int cnt = 0;
        
        // total profit earned
        int totProfit = 0;

        // pair the profit and deadline of
        // all the jos together
        List<Tuple<int, int>> jobs = new List<Tuple<int, int>>();
        for (int i = 0; i < n; i++)
        {
            jobs.Add(new Tuple<int, int>(profit[i], deadline[i]));
        }

        // sort the jobs based on profit
        // in decreasing order
        jobs.Sort((a, b) => b.Item1.CompareTo(a.Item1));

        // array to check time slot for job
        int[] slot = new int[n];
        for (int i = 0; i < n; i++)
        {
            int start = Math.Min(n, jobs[i].Item2) - 1;
            for (int j = start; j >= 0; j--)
            {
                // if slot is empty
                if (slot[j] == 0)
                {
                    slot[j] = 1;
                    cnt++;
                    totProfit += jobs[i].Item1;
                    break;
                }
            }
        }
        
        return new List<int> { cnt, totProfit };
    }

    static void Main() {
        int[] deadline = { 2, 1, 2, 1, 1 };
        int[] profit = { 100, 19, 27, 25, 15 };
        List<int> ans = JobSequencing(deadline, profit);
        Console.WriteLine(ans[0] + " " + ans[1]);
    }
}
JavaScript
// JavaScript program to solve job sequencing
// problem with maximum profit

function jobSequencing(deadline, profit) {
    let n = deadline.length;
    
    // total job count which is done
    let cnt = 0;
    
    // total profit earned
    let totProfit = 0;

    // pair the profit and deadline of
    // all the jos together
    let jobs = [];
    for (let i = 0; i < n; i++) {
        jobs.push([profit[i], deadline[i]]);
    }

    // sort the jobs based on profit
    // in decreasing order
    jobs.sort((a, b) => b[0] - a[0]);

    // array to check time slot for job
    let slot = new Array(n).fill(0);
    
    for (let i = 0; i < n; i++) {
        let start = Math.min(n, jobs[i][1]) - 1;
        for (let j = start; j >= 0; j--) {

            // if slot is empty
            if (slot[j] === 0) {
                slot[j] = 1;
                cnt++;
                totProfit += jobs[i][0];
                break;
            }
        }
    }
    
    return [cnt, totProfit];
}

// Driver Code 
const deadline = [2, 1, 2, 1, 1];
const profit = [100, 19, 27, 25, 15];
const ans = jobSequencing(deadline, profit);
console.log(ans[0], ans[1]);

Output
2 127

[Expected Approach] Greedy Approach, Sorting and Priority Queue - O(n * log(n)) Time and O(n) Space

The main idea is to sort the jobs based on their deadlines in ascending order. This ensures that jobs with earlier deadlines are processed first, preventing situations where a job with a short deadline remains unscheduled because a job with a later deadline was chosen instead. We use a min-heap to keep track of the selected jobs, allowing us to efficiently replace lower-profit jobs when a more profitable job becomes available.

Step by Step implementation:

  • Store jobs as pairs of (Deadline, Profit).
  • Sort Jobs Based on Deadline: We sort the jobs array in ascending order of deadline so that we prioritize jobs with earlier deadlines are considered first.
  • For each job (deadline, profit) in the sorted list:
    • If the job can be scheduled within its deadline (i.e., the number of jobs scheduled so far is less than the deadline), push its profit into the heap.
    • If the heap is full (equal to deadline), replace the existing lowest profit job with the current job if it has a higher profit.
    • This ensures that we always keep the most profitable jobs within the available slots.
  • Traverse through the heap and store the total profit and the count of jobs.
C++
// C++ program to solve job sequencing
// problem with maximum profit

#include<bits/stdc++.h>
using namespace std;

vector<int> jobSequencing(vector<int> &deadline, vector<int> &profit) {
     int n = deadline.size();
    vector<int> ans = {0, 0};

    // pair the profit and deadline of
    // all the jos together
    vector<pair<int, int>> jobs;
    for (int i = 0; i < n; i++) {
        jobs.push_back({deadline[i], profit[i]});
    }

    // sort the jobs based on deadline
    // in ascending order
    sort(jobs.begin(), jobs.end());

    // to maintain the scheduled jobs based on profit
    priority_queue<int, vector<int>, greater<int>> pq;

    for (const auto &job : jobs) {
        
        // if job can be scheduled within its deadline
        if (job.first > pq.size())
            pq.push(job.second);
        
        // Replace the job with the lowest profit
        else if (!pq.empty() && pq.top() < job.second) {
            pq.pop();
            pq.push(job.second);
        }
    }

    while (!pq.empty()) {
        ans[1] += pq.top();
        pq.pop();
        ans[0]++;
    }

    return ans;
}

int main() {
    vector<int> deadline = {2, 1, 2, 1, 1};
    vector<int> profit = {100, 19, 27, 25, 15};
    vector<int> ans = jobSequencing(deadline, profit);
    cout<<ans[0]<<" "<<ans[1];
    return 0;
}
Java
// Java program to solve job sequencing
// problem with maximum profit
import java.util.*;

public class GfG {
    
     static ArrayList<Integer> jobSequencing(int[] deadline, int[] profit) {
        int n = deadline.length;
        ArrayList<Integer> ans = new ArrayList<>(Arrays.asList(0, 0));
        
        // Pair the profit and deadline of all the jobs together
        List<int[]> jobs = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            jobs.add(new int[]{deadline[i], profit[i]});
        }

        // Sort the jobs based on deadline in ascending order
        jobs.sort(Comparator.comparingInt(a -> a[0]));
        
        // Min-heap to maintain the scheduled jobs based on profit
        PriorityQueue<Integer> pq = new PriorityQueue<>();

        for (int[] job : jobs) {
            
            // If job can be scheduled within its deadline
            if (job[0] > pq.size()) {
                pq.add(job[1]);
            } 
            
            // Replace the job with the lowest profit
            else if (!pq.isEmpty() && pq.peek() < job[1]) {
                pq.poll();
                pq.add(job[1]);
            }
        }

        while (!pq.isEmpty()) {
            ans.set(1, ans.get(1) + pq.poll());
            ans.set(0, ans.get(0) + 1);
        }

        return ans;
    }

    public static void main(String[] args) {
        int[] deadline = {2, 1, 2, 1, 1};
        int[] profit = {100, 19, 27, 25,15};
        ArrayList<Integer> result = jobSequencing(deadline, profit);
        System.out.println(result.get(0) + " " + result.get(1));
    }
}
Python
# Python program to solve job sequencing
# problem with maximum profit
import heapq

def jobSequencing(deadline, profit):
    n = len(deadline)
    ans = [0, 0]
    
    # pair the profit and deadline of
    # all the jos together
    jobs = [(deadline[i], profit[i]) for i in range(n)]
    
    # sort the jobs based on deadline
    # in ascending order
    jobs.sort()
    
    # to maintain the scheduled jobs based on profit
    pq = []
    
    for job in jobs:
        
        # if job can be scheduled within its deadline
        if job[0] > len(pq):
            heapq.heappush(pq, job[1])
        # Replace the job with the lowest profit
        elif pq and pq[0] < job[1]:
            heapq.heappop(pq)
            heapq.heappush(pq, job[1])
    
    while pq:
        ans[1] += heapq.heappop(pq)
        ans[0] += 1
    
    return ans

if __name__ == "__main__":
    deadline = [2, 1, 2, 1, 1]
    profit = [100, 19, 27, 25,15]
    ans = jobSequencing(deadline, profit)
    print(ans[0], ans[1])
C#
// C# program to solve job sequencing
// problem with maximum profit

using System;
using System.Collections.Generic;

class GfG {
     static List<int> jobSequencing(int[] deadline, int[] profit) {
        int n = deadline.Length;
        List<int> ans = new List<int> { 0, 0 };

        // pair the profit and deadline of
        // all the jobs together
        List<(int, int)> jobs = new List<(int, int)>();
        for (int i = 0; i < n; i++) {
            jobs.Add((deadline[i], profit[i]));
        }

        // sort the jobs based on deadline
        // in ascending order
        jobs.Sort((a, b) => a.Item1.CompareTo(b.Item1));

        // to maintain the scheduled jobs based on profit
        SortedSet<int> pq = new SortedSet<int>();

        foreach (var job in jobs) {
            
            // if job can be scheduled within its deadline
            if (pq.Count < job.Item1) {
                pq.Add(job.Item2);
            }
            
            // Replace the job with the lowest profit
            else if (pq.Count > 0 && pq.Min < job.Item2) {
                pq.Remove(pq.Min);
                pq.Add(job.Item2);
            }
        }

        foreach (int value in pq) {
            ans[1] += value;
            ans[0]++;
        }

        return ans;
    }

    public static void Main() {
        int[] deadline = { 2, 1, 2, 1, 1 };
        int[] profit = { 100, 19, 27, 25, 15 };
        List<int> ans = jobSequencing(deadline, profit);
        Console.WriteLine(ans[0] + " " + ans[1]);
    }
}
JavaScript
// JavaScript program to solve job sequencing
// problem with maximum profit

class MinHeap {
    constructor() {
        this.heap = [];
    }

    push(val) {
        this.heap.push(val);
        this.heapifyUp();
    }

    pop() {
        if (this.heap.length === 1) return this.heap.pop();
        let top = this.heap[0];
        this.heap[0] = this.heap.pop();
        this.heapifyDown();
        return top;
    }

    top() {
        return this.heap[0];
    }

    size() {
        return this.heap.length;
    }

    heapifyUp() {
        let idx = this.heap.length - 1;
        while (idx > 0) {
            let parent = Math.floor((idx - 1) / 2);
            if (this.heap[parent] <= this.heap[idx]) break;
            [this.heap[parent], this.heap[idx]] =
            [this.heap[idx], this.heap[parent]];
            idx = parent;
        }
    }

    heapifyDown() {
        let idx = 0;
        while (2 * idx + 1 < this.heap.length) {
            let left = 2 * idx + 1, right = 2 * idx + 2;
            let smallest = left;
            if (right < this.heap.length && this.heap[right] 
            < this.heap[left]) smallest = right;
            if (this.heap[idx] <= this.heap[smallest]) break;
            [this.heap[idx], this.heap[smallest]] =
            [this.heap[smallest], this.heap[idx]];
            idx = smallest;
        }
    }
}

function jobSequencing(deadline, profit) {
    let n = deadline.length;
    let ans = [0, 0];

    // pair the profit and deadline of
    // all the jobs together
    let jobs = [];
    for (let i = 0; i < n; i++) {
        jobs.push([deadline[i], profit[i]]);
    }

    // sort the jobs based on deadline
    // in ascending order
    jobs.sort((a, b) => a[0] - b[0]);

    // to maintain the scheduled jobs based on profit
    let pq = new MinHeap();

    for (let job of jobs) {
        
        // if job can be scheduled within its deadline
        if (job[0] > pq.size()) {
            pq.push(job[1]);
        }
        
        // Replace the job with the lowest profit
        else if (pq.size() > 0 && pq.top() < job[1]) {
            pq.pop();
            pq.push(job[1]);
        }
    }

    while (pq.size() > 0) {
        ans[1] += pq.pop();
        ans[0]++;
    }

    return ans;
}

// Driver Code 
let deadline = [2, 1, 2, 1, 1];
let profit = [100, 19, 27, 25, 15];
let ans = jobSequencing(deadline, profit);
console.log(ans[0] + " " + ans[1]);

Output
2 127

[Alternate Approach] Using Disjoint Set - O(n * log(d)) Time and O(d) Space

The job sequencing can also be done using disjoint set based on the maximum deadline of all the jobs. This approach is explained in article Job Sequencing - Using Disjoint Set.


Next Article
Article Tags :
Practice Tags :

Similar Reads