返回

从Java&C++题解汲取经验,畅游LeetCode 857:雇佣K名工人的最低成本

后端

导言

算法是计算机科学的核心,也是解决复杂问题的利器。LeetCode作为备受推崇的算法题库,吸引了众多编程爱好者和竞赛选手前来挑战。本篇博文将聚焦于LeetCode 857:雇佣K名工人的最低成本这一问题,为你提供详细的题解和拓展思路,助你从容应对类似问题。

问题剖析

题目如下:

一家公司雇佣了N名工人,每位工人的工资不同。公司需要雇佣K名工人,并且需要支付最低的总工资。已知每位工人的工资,请你计算出公司雇佣K名工人所需的最低总工资。

Java题解

Java语言因其简洁明了、易于上手的特点而受到广泛欢迎。我们先来看看Java题解。

import java.util.*;

class Solution {
    public int minCostToHireWorkers(int[] quality, int[] wage, int K) {
        // 将工人按质量工资比升序排序
        List<Worker> workers = new ArrayList<>();
        for (int i = 0; i < quality.length; i++) {
            workers.add(new Worker(quality[i], wage[i]));
        }
        Collections.sort(workers, (a, b) -> Double.compare(a.ratio, b.ratio));

        // 计算前K个工人的总质量
        int totalQuality = 0;
        for (int i = 0; i < K; i++) {
            totalQuality += workers.get(i).quality;
        }

        // 计算前K个工人的最低总工资
        int minCost = Integer.MAX_VALUE;
        for (int i = 0; i <= workers.size() - K; i++) {
            int cost = 0;
            for (int j = i; j < i + K; j++) {
                cost += workers.get(j).wage;
            }
            minCost = Math.min(minCost, cost);
        }

        // 返回最低总工资
        return minCost;
    }

    private static class Worker {
        int quality;
        int wage;
        double ratio;

        public Worker(int quality, int wage) {
            this.quality = quality;
            this.wage = wage;
            this.ratio = (double) wage / quality;
        }
    }
}

C++题解

C++语言凭借其强大的性能和丰富的库函数,在算法竞赛中也备受青睐。下面我们来看看C++题解。

#include <vector>
#include <algorithm>

using namespace std;

class Solution {
public:
    int minCostToHireWorkers(vector<int>& quality, vector<int>& wage, int K) {
        // 将工人按质量工资比升序排序
        vector<pair<double, int>> workers;
        for (int i = 0; i < quality.size(); i++) {
            workers.push_back(make_pair((double) wage[i] / quality[i], quality[i]));
        }
        sort(workers.begin(), workers.end());

        // 计算前K个工人的总质量
        int totalQuality = 0;
        for (int i = 0; i < K; i++) {
            totalQuality += workers[i].second;
        }

        // 计算前K个工人的最低总工资
        int minCost = INT_MAX;
        for (int i = 0; i <= workers.size() - K; i++) {
            int cost = 0;
            for (int j = i; j < i + K; j++) {
                cost += workers[j].first * workers[j].second;
            }
            minCost = min(minCost, cost);
        }

        // 返回最低总工资
        return minCost;
    }
};

拓展思路

除了上述两种语言的题解,我们还可以从以下几个方面进行拓展。

  • 使用贪心算法优化复杂度。 由于工人按质量工资比升序排序,我们可以采用贪心策略,每次选择质量工资比最小的工人,这样可以保证在满足K个工人要求的前提下,总工资最低。
  • 利用数据结构优化时间复杂度。 我们可以使用优先队列来存储工人,这样可以快速找到质量工资比最小的工人,从而降低时间复杂度。
  • 考虑其他约束条件。 在实际场景中,可能还存在其他约束条件,例如工人的工作时间、技能要求等。我们需要根据具体情况进行分析,设计出满足所有约束条件的算法。

总结

LeetCode 857:雇佣K名工人的最低成本这道题看似简单,但其中蕴藏着丰富的算法思想和优化技巧。希望通过本篇博文的讲解,你能对这类问题有更深入的理解。在未来的编程实践中,你将能够轻松应对类似问题,展现出你的算法功底。

附录:类和方法的学习

在Java和C++题解中,我们使用了类和方法来组织代码。类是对象的蓝图,方法是类中的操作。我们可以通过类和方法来封装数据和行为,从而使代码更加清晰易读。

在Java中,类和方法的定义如下:

public class Worker {
    private int quality;
    private int wage;

    public Worker(int quality, int wage) {
        this.quality = quality;
        this.wage = wage;
    }

    public double getRatio() {
        return (double) wage / quality;
    }
}

在C++中,类和方法的定义如下:

class Worker {
private:
    int quality;
    int wage;

public:
    Worker(int quality, int wage) {
        this->quality = quality;
        this->wage = wage;
    }

    double getRatio() {
        return (double) wage / quality;
    }
};

希望通过这些示例,你能对类和方法的使用有更深入的理解。在未来的编程实践中,你将能够熟练运用类和方法来组织代码,编写出更加高效、易读的程序。