leetcode

Leetcode Solutions (0x6A73)
git clone https://git.pngu.org/leetcode
Log | Files | Refs | Submodules | README

commit 45479952ecfb1e41ca79982b36d0fcbec35c0476
parent d8e6f259d79bd329253e723e9768120f68aa56fe
Author: Jack Sangdahl <jack@pngu.org>
Date:   Thu, 22 Jan 2026 15:34:26 -0700

1723. find minimum time to finish all jobs

Diffstat:
Afind_min_time_finish_jobs.c | 161+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Afind_min_time_finish_jobs.py | 46++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 207 insertions(+), 0 deletions(-)

diff --git a/find_min_time_finish_jobs.c b/find_min_time_finish_jobs.c @@ -0,0 +1,161 @@ +// 1723. Find Minimum Time to Finish All Jobs +#include "leetcode.h" + +/* + * you are given an integer array 'jobs' where 'jobs[i]' is the amount of time + * it takes to complete the i'th job. there are 'k' workers that you can assign + * jobs to. each job should be assigned to exactly one worker. the working time + * of a worker is the sum of the time it takes to complete all jobs assigned to + * them. your goal is to devise an optimal assignment such that the maximum + * working time of any worker is minimised. return the minimum possible maximum + * working time of any assignment. + */ + +struct node { + int key; + struct node *left; + struct node *right; + int height; +}; + +int height(struct node *obj) { + if (!obj) + return 0; + return obj->height; +} + +struct node *node_init(int key) { + struct node *obj = (struct node *)malloc(sizeof(struct node)); + obj->key = key; + obj->left = NULL; + obj->right = NULL; + obj->height = 1; + return obj; +} + +struct node *rotate_right(struct node *y) { + struct node *x = y->left, *tmp = x->right; + x->right = y; + y->left = tmp; + y->height = fmax(height(y->left), height(y->right)) + 1; + x->height = fmax(height(x->left), height(x->right)) + 1; + return x; +} + +struct node *rotate_left(struct node *x) { + struct node *y = x->right, *tmp = y->left; + y->left = x; + x->right = tmp; + x->height = fmax(height(x->left), height(x->right)) + 1; + y->height = fmax(height(y->left), height(y->right)) + 1; + return y; +} + +int get_balance(struct node *obj) { + if (!obj) + return 0; + return height(obj->left) - height(obj->right); +} + +struct node *node_insert(struct node *obj, int key) { + if (!obj) + return node_init(key); + if (key < obj->key) + obj->left = node_insert(obj->left, key); + else if (key > obj->key) + obj->right = node_insert(obj->right, key); + else + return obj; + obj->height = fmax(height(obj->left), height(obj->right)) + 1; + int balance = get_balance(obj); + if (balance > 1 && key < obj->left->key) + return rotate_right(obj); + if (balance < -1 && key > obj->right->key) + return rotate_left(obj); + if (balance > 1 && key > obj->left->key) { + obj->left = rotate_left(obj->left); + return rotate_right(obj); + } + if (balance < -1 && key < obj->right->key) { + obj->right = rotate_right(obj->right); + return rotate_left(obj); + } + return obj; +} + +bool check(struct node *obj, int val) { + if (!obj) + return false; + else { + if (obj->key == val) + return true; + else if (obj->key < val) + return check(obj->right, val); + else + return check(obj->left, val); + } +} + +void assign(int *assignments, int id, int *jobs, int k, int *ans) { + int i; + if (id == -1) { + int res = INT_MIN; + for (int i = 0; i < k; i++) + res = fmax(res, assignments[i]); + *ans = fmin(*ans, res); + return; + } else { + struct node *root = NULL; + for (int i = 0; i < k; i++) { + assignments[i] += jobs[id]; + if (check(root, assignments[i])) { + assignments[i] -= jobs[id]; + continue; + } + root = node_insert(root, assignments[i]); + if (assignments[i] < *ans) + assign(assignments, id - 1, jobs, k, ans); + assignments[i] -= jobs[id]; + } + } +} + +int cmp(const void *a, const void *b) { return *((int *)a) - *((int *)b); } + +int helper(int *jobs, int n, int k) { + int *assignments = (int *)calloc(k, sizeof(int)); + int i = n - 1, dir = -1; + while (i >= 0) { + int j = fmax(i - k + 1, 0); + if (dir == -1) { + int m = i - j + 1; + for (int j = 0; j < m; j++) + assignments[j] += jobs[i - j]; + } else { + int m = i - j + 1; + for (int j = 0; j < m; j++) + assignments[m - 1 - j] += jobs[i - j]; + } + i = j - 1; + dir = -dir; + } + int res = assignments[0]; + for (int i = 1; i < k; i++) + res = fmax(res, assignments[i]); + free(assignments); + return res; +} + +int minimumTimeRequired(int *jobs, int jobsSize, int k) { + qsort(jobs, jobsSize, sizeof(int), cmp); + int i, ans = helper(jobs, jobsSize, k); + int *assignments = (int *)calloc(k, sizeof(int)); + assign(assignments, jobsSize - 1, jobs, k, &ans); + return ans; +} + +int main() { + int j1[] = {3, 2, 3}, j2[] = {1, 2, 4, 7, 8}; + printf("%d\n", minimumTimeRequired(j1, ARRAY_SIZE(j1), 3)); // expect: 3 + printf("%d\n", minimumTimeRequired(j2, ARRAY_SIZE(j2), 2)); // expect: 11 +} diff --git a/find_min_time_finish_jobs.py b/find_min_time_finish_jobs.py @@ -0,0 +1,46 @@ +# 1723. Find Minimum Time to Finish All Jobs +from functools import lru_cache +from itertools import product + +""" +you are given an integer array 'jobs' where 'jobs[i]' is the amount of time +it takes to complete the i'th job. there are 'k' workers that you can assign +jobs to. each job should be assigned to exactly one worker. the working time +of a worker is the sum of the time it takes to complete all jobs assigned to +them. your goal is to devise an optimal assignment such that the maximum +working time of any worker is minimised. return the minimum possible maximum +working time of any assignment. +""" + + +class Solution(object): + def minimumTimeRequired(self, jobs, k): + """ + :type jobs: List[int] + :type k: int + :rtype: int + """ + n = len(jobs) + cost = [0] * (1 << n) + for i, j in product(range(1 << n), range(n)): + cost[i] += jobs[j] * ((i >> j) & 1) + + @lru_cache(None) + def dp(mask, k): + if k == 1: + return cost[mask] + submask, res = mask, cost[mask] + while (submask - 1) & mask: + submask = (submask - 1) & mask + if cost[submask] >= res: + continue + res = min(res, max(cost[submask], dp(mask ^ submask, k - 1))) + return res + + return dp((1 << n) - 1, k) + + +if __name__ == "__main__": + obj = Solution() + print(obj.minimumTimeRequired(jobs=[3, 2, 3], k=3)) + print(obj.minimumTimeRequired(jobs=[1, 2, 4, 7, 8], k=2))