leetcode-575-Distribute Candies(计算一个数组中元素的种类的快速方法)

题目描述:

Given an integer array with even length, where different numbers in this array represent different kinds of candies. Each number means one candy of the corresponding kind. You need to distribute these candies equally in number to brother and sister. Return the maximum number of kinds of candies the sister could gain.

Example 1:

Input: candies = [1,1,2,2,3,3]
Output: 3
Explanation:
There are three different kinds of candies (1, 2 and 3), and two candies for each kind.
Optimal distribution: The sister has candies [1,2,3] and the brother has candies [1,2,3], too.
The sister has three different kinds of candies.

Example 2:

Input: candies = [1,1,2,3]
Output: 2
Explanation: For example, the sister has candies [2,3] and the brother has candies [1,1].
The sister has two different kinds of candies, the brother has only one kind of candies.

Note:

  1. The length of the given array is in range [2, 10,000], and will be even.
  2. The number in given array is in range [-100,000, 100,000].

要完成的函数:

int distributeCandies(vector<int>& candies)

说明:

1、这道题给了一个vector,里面每个数字代表一种糖果,比如[1,1,2,2,3,3],代表1糖果有2个,2糖果有2个,3糖果有2个。这个vector的长度必定为偶数,要把糖果均分给哥哥和妹妹,妹妹能分到的一半糖果最多能有多少种。

2、假如我们知道有n种糖果,妹妹能分到m个糖果,如果n<=m,那说明里面重复的很多,比如[1,1,1,1,2,2],妹妹能分到3个糖果,而糖果只有2种,那么妹妹最多能得到的种类数也不会超过n,只能多拿一些重复的了。

如果n>m,也就是说糖果种类比妹妹能拿到的糖果个数还多,那说明有很多种类各异的,比如[1,2,3,4,5,5],妹妹能分到3个糖果,而糖果有5种,那么妹妹能得到的最多种类数也只有3种。

思路清晰,我们可以构造如下代码:

    int distributeCandies(vector<int>& candies)
{
int total=candies.size()/;
set<int>s1(candies.begin(),candies.end());
int kind=s1.size();
if(kind<=total)
return kind;
else
return total;
}

这是最简单的实现方法,利用set得到了种类数。

上述代码实测333 ms,beats 30.13% of cpp submissions。

3、改进:

我们使用set,其实是把vector中的元素一个个加进去,每碰到一个元素就判断这个元素有没有出现过,如果有就不加入,如果没有就加入。判断的这个过程其实又是一个循环。

所以set的办法其实是双重循环,O(n^2)。

但我们其实并不需要处理数,我们所需要的,只是知道vector中有多少种数。

所以我们其实可以对vector做一个快速排序,然后做单重循环,如果前一个数和后一个数不一样,那么种类数+1。

这样子的排序+单重循环的方法,时间复杂度低于O(n^2)。

代码如下:

    int distributeCandies(vector<int>& candies)
{
int total=candies.size()/;
sort(candies.begin(),candies.end());
int kind=;
for(int i=;i<candies.size()-;i++)
{
if(candies[i+]!=candies[i])
kind++;
}
if(kind<=total)
return kind;
else
return total;
}

上述代码实测258ms,beats 82.50% of cpp submissions。

4、另一种方法:

因为题目限定了数的范围在[-100,000,100,000],所以其实我们可以开辟一个长度为200001的vector。

接着迭代给定vector,更新长度为200001的vector的值。

最后再迭代这个长vector,看一下有多少种。

但是由于长vector长度太长了,所以这种方法花费时间很多,不是很推荐。这里只是做一个扩展介绍。

这道题的启示还是:当碰到需要判断vector中有多少种数字时,可以先做一个快速排序,接着单重循环。

上一篇:iOS 微信支付SDK与微信友盟分享两者同时集成时,出现的问题与解决之路。


下一篇:lua table表