zoukankan      html  css  js  c++  java
  • 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()/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中有多少种数字时,可以先做一个快速排序,接着单重循环。

  • 相关阅读:
    python_day11 mysql
    python_day10 多线程 协程 IO模型
    python_day09 多进程 多线程 协程 paramiko模块
    python_day08 接口与归一化设计 多态与多态性 封装 面向对象高级 异常处理 网络编程
    python_day07 常用模块xml/configparser/hashlib/subprocess 面向对象程序设计
    python_day06 匿名函数与内置函数 常用模块
    python_day05 协程函数 面向过程编程 递归和二分法 模块和包的使用 常用模块 开发代码规范
    python_day04 函数嵌套 名称空间和作用域 闭包 装饰器 迭代器 生成器 列表解析 三元表达式 生成器表达式
    python_day03 文件处理复习和函数定义调用参数对象
    python_day02 基本数据类型操作,字符编码,文件处理
  • 原文地址:https://www.cnblogs.com/chenjx85/p/8991589.html
Copyright © 2011-2022 走看看