Untitled

 avatar
unknown
plain_text
18 days ago
5.1 kB
3
Indexable
/********************************************************************* JAVA *********************************************************************/
// Approach-1 (Brute Force - Heap + Math) - TLE
// T.C : O(n * (n + klogk))
// S.C : O(n+k)
class Solution {
    public double mincostToHireWorkers(int[] quality, int[] min_wage, int k) {
        int n = quality.length;

        double result = Double.MAX_VALUE; // maximum representable finite floating-point (double) number

        for (int fixed = 0; fixed < n; fixed++) {
            double fixedRatio = (double) min_wage[fixed] / quality[fixed];

            // Create a group of workers whose wage-to-quality ratio is greater than or equal to the fixed's ratio
            double[] group = new double[n];
            int groupSize = 0;
            for (int worker = 0; worker < n; worker++) {
                double worker_wage = quality[worker] * fixedRatio;
                if (worker_wage >= min_wage[worker]) {
                    group[groupSize++] = worker_wage;
                }
            }

            if (groupSize < k)
                continue;

            PriorityQueue<Double> pq = new PriorityQueue<>(groupSize, Collections.reverseOrder());
            double sum = 0;

            // Calculate the sum of wages for the selected group of workers
            for (int i = 0; i < groupSize; i++) {
                sum += group[i];
                pq.offer(group[i]);

                if (pq.size() > k) {
                    sum -= pq.poll();
                }
            }

            result = Math.min(result, sum);
        }

        return result;
    }
}


// Approach-2 (Improved Brute Force - Heap + Math) - TLE
// T.C : O(nlogn + n * (n + klogk)) - This is worst case when no one got eliminated 
// S.C : O(n+k)
class Solution {
    public double mincostToHireWorkers(int[] quality, int[] min_wage, int k) {
        int n = quality.length;

        double result = Double.MAX_VALUE; // maximum representable finite floating-point (double) number

        // Calculate the wage-to-quality ratio for each worker and store in a pair
        double[][] worker_ratio = new double[n][2];
        for (int worker = 0; worker < n; worker++) {
            worker_ratio[worker][0] = (double) min_wage[worker] / quality[worker];
            worker_ratio[worker][1] = quality[worker];
        }

        // Sort the workers based on their wage-to-quality ratio
        Arrays.sort(worker_ratio, (a, b) -> Double.compare(a[0], b[0]));

        for (int fixed = k - 1; fixed < n; fixed++) {
            double fixedRatio = worker_ratio[fixed][0];

            // Create a group of workers whose wage-to-quality ratio is less than or equal to the current fixed's ratio
            double[] group = new double[fixed + 1];
            for (int worker = 0; worker <= fixed; worker++) {
                double worker_wage = worker_ratio[worker][1] * fixedRatio;
                group[worker] = worker_wage;
            }

            PriorityQueue<Double> pq = new PriorityQueue<>(group.length, Collections.reverseOrder());
            double sum = 0;

            // Calculate the sum of wages for the selected group of workers
            for (double wage : group) {
                sum += wage;
                pq.offer(wage);

                if (pq.size() > k) {
                    sum -= pq.poll();
                }
            }

            result = Math.min(result, sum);
        }

        return result;
    }
}


// Approach-3 (Optimal)
// T.C : O(nlogn + klogk + n*log(k))
// S.C : O(n+k)
class Solution {
    public double mincostToHireWorkers(int[] quality, int[] min_wage, int k) {
        int n = quality.length;

        // Calculate the wage-to-quality ratio for each worker and store in a pair
        double[][] worker_ratio = new double[n][2];
        for (int worker = 0; worker < n; worker++) {
            worker_ratio[worker][0] = (double) min_wage[worker] / quality[worker];
            worker_ratio[worker][1] = quality[worker];
        }
        // Sort the workers based on their wage-to-quality ratio
        Arrays.sort(worker_ratio, (a, b) -> Double.compare(a[0], b[0]));

        PriorityQueue<Integer> pq = new PriorityQueue<>(Collections.reverseOrder());


        // fixed size sliding window approach
        double sum_quality = 0;
        for (int i = 0; i < k; i++) {
            pq.add((int) worker_ratio[i][1]); // Push all qualities in max-heap
            sum_quality += worker_ratio[i][1]; // Find sum of qualities
        }

        double fixedRatio = worker_ratio[k - 1][0];
        double result = fixedRatio * sum_quality;

        for (int fixed = k; fixed < n; fixed++) {
            sum_quality -= pq.poll();
            sum_quality += worker_ratio[fixed][1];
            pq.add(worker_ratio[fixed][1]);
            fixedRatio = worker_ratio[fixed][0];
            result = Math.min(result, fixedRatio * sum_quality);
        }

        return result;
    }
}
Leave a Comment