1. 程式人生 > >leetcode-575-Distribute Candies(計算一個數組中元素的種類的快速方法)

leetcode-575-Distribute Candies(計算一個數組中元素的種類的快速方法)

題目 簡單的 快速排序 span NPU bin 又是 return 推薦

題目描述:

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()/2;
        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()/2;
        sort(candies.begin(),candies.end());
        int kind=1;
        for(int i=0;i<candies.size()-1;i++)
        {
            if(candies[i+1]!=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中有多少種數字時,可以先做一個快速排序,接著單重循環。

leetcode-575-Distribute Candies(計算一個數組中元素的種類的快速方法)