完成一半题目

70 阅读2分钟

🎈 算法并不一定都是很难的题目,也有很多只是一些代码技巧,多进行一些算法题目的练习,可以帮助我们开阔解题思路,提升我们的逻辑思维能力,也可以将一些算法思维结合到业务代码的编写思考中。简而言之,平时进行的算法习题练习带给我们的好处一定是不少的,所以让我们一起来养成算法练习的习惯。今天练习的题目是一道比较简单的题目 ->完成一半题目

问题描述

有 N 位扣友参加了微软与力扣举办了「以扣会友」线下活动。主办方提供了 2*N 道题目,整型数组 questions 中每个数字对应了每道题目所涉及的知识点类型。 若每位扣友选择不同的一题,请返回被选的 N 道题目至少包含多少种知识点类型。

示例 1:

输入:questions = [2,1,6,2]

输出:1

解释:有 2 位扣友在 4 道题目中选择 2 题。 可选择完成知识点类型为 2 的题目时,此时仅一种知识点类型 因此至少包含 1 种知识点类型。

示例 2:

输入:questions = [1,5,1,3,4,5,2,5,3,3,8,6]

输出:2

解释:有 6 位扣友在 12 道题目中选择题目,需要选择 6 题。 选择完成知识点类型为 3、5 的题目,因此至少包含 2 种知识点类型。

提示:

  • questions.length == 2*n
  • 2 <= questions.length <= 10^5
  • 1 <= questions[i] <= 1000

思路分析

首先我们应该要先理解一下题目意思,题目会给我们一个长度为2*n的数组,表示2*n道题目每道题目所涉及的知识点类型,现在我们需要从其中选出n道,并计算选出的n道至少包含多少种知识点类型。

题目中的关键字是至少,也就是说我们要考虑的是选择知识点重复最多的情况,所以我们可以先对题目涉及知识点进行统计,计算出每种知识点类型对应的题目数量,总共有n个人,每人可以选择一道题目,所以应该选择n道题目,而且要优先选择知识点最多的题目。

  • 统计题目各种知识点类型的数量

可以使用哈希表来保存各种知识点类型的题目数量

const map = {};
for (const k of questions) {
    map[k] = (map[k] || 0) + 1;
}
  • 将各类知识点类型题目数量从多到少进行排序

通过Object.values(),我们可以快速获取到对象的值,这里的值即是各种知识点类型题目的数量,我们先将其从大到小进行排序。

const values = Object.values(map).sort((a, b) => b - a);
  • 计算n道题目至少包含知识点数量

要使包含的知识点最少,我们需要优先选择数量较多的知识题相关的题目,前面我们已经将各种知识点类型题目的数量统计出来并进行了排序,我们只需要按从大到小的顺序选择相关题目即可。

let res = 0,
count = 0;
while (count < questions.length / 2) {
    count += values[res];
    res++;
}

AC 代码

完整 AC 代码如下:

/**
 * @param {number[]} questions
 * @return {number}
 */
var halfQuestions = function (questions) {
  const map = {};
  for (const k of questions) {
    map[k] = (map[k] || 0) + 1;
  }
  const values = Object.values(map).sort((a, b) => b - a);
  let res = 0,
    count = 0;
  while (count < questions.length / 2) {
    count += values[res];
    res++;
  }
  return res;
};

说在后面

🎉 这里是 JYeontu,现在是一名前端工程师,有空会刷刷算法题,平时喜欢打羽毛球 🏸 ,平时也喜欢写些东西,既为自己记录 📋,也希望可以对大家有那么一丢丢的帮助,写的不好望多多谅解 🙇,写错的地方望指出,定会认真改进 😊,在此谢谢大家的支持,我们下文再见 🙌。