算法期中1000. 分组

来源:互联网 发布:c删除数组中的一个元素 编辑:程序博客网 时间:2024/06/05 17:52

Description
对于一个整数数列A[0], A[1], …, A[N-1]进行分组,要求每组1到2个数,并且同组之和不能大于w. 求最少可以分成多少组.

1 <= N <= 100000, 1 <= A[i] <= w <= 1000000000.

请实现下面Solution类中计算minPartition(A, w)的函数.

class Solution {public:       int minPartition(vector<int> A, int w) {       }};

例1:当A = {2, 5, 4, 3}, w = 5, minPartition(A, w)返回3. 将2和3放一组,4和5各自单独作为一组,共3组.

例2:当A = {2, 5, 4, 3}, w = 7, minPartition(A, w)返回2. 将2和5放一组,3和4一组,共2组.

注意:你只需要提交Solution类的代码,你在本地可以编写main函数测试程序,但不需要提交main函数的代码. 注意不要修改类和函数的名称.

解析:
当时没想出来,一直想啥动态规划。之后和室友交流下,其实思路很简单。自己居然把排序等一般的方法都忘了,思维太局限了。leetcode要认真打了啊。。。
把A从小至大排序。找到能和最小的数字匹配的最大的数字的下标,这些数字一一配对,处理一下,即可得最大的对数。然鹅我的思路还是WA,参考了别人的代码才发现自己的疏漏。第一个函数是我的错误代码,第二个是正确的。
正确思路举例:w = 8,序列为2 4 5 6 7
先把数组从小到大排序,尽可能多划分组,就要求小的和尽量大的一组。
head指针从头取剩余最小的,tail指针从尾部找能和head相加后小于w的最大值。tail每轮循环都要向向前移动一位,即tail–,同时res++,因为tail所指向的数字必须单独列为一组。如果tail所值的数字和head所指的数字相加满足要求,则head++,tail–,res++(因为得到一组)。最终假设还剩下两个数,head指向第一个,tail指向第二个数。① 二者相加符合条件,则head++,tail–并且res++。不满足head < tail,结束。②二者相加不符合条件,则tail–,res++,进入下一轮循环此时head == tail,不符合head < tail,所以结束。但是head 和tail所指的数字仍自成一组,故res++。
代码:

class Solution {public:    /*这个方法一直令head = 0     *是错误的,如2 4 5 6 7, w = 8,     *当tail到6的时候,2 + 6 <= 8没错     *但是4 + 5 = 9,中间的就不一定符合要求     */    int minPartitionWrong(vector<int> A, int w) {          sort(A.begin(), A.end());  // 从小至大排序        int pairsNum = 0;        int doublePairsNum;        int size = A.size();        for (doublePairsNum = size - 1; doublePairsNum >= 0; doublePairsNum--) {            int sum = A[doublePairsNum] + A[0]; // 找到符合条件的最大的数下标            if (sum <= w) break;        }        pairsNum = (doublePairsNum + 1) / 2;        return size - pairsNum;    }

正确的解答:

    int minPartition(vector<int> A, int w) {        sort(A.begin(), A.end());  // 从小至大排序        int tail, head = 0, res = 0;        int size = A.size();        for (tail = size - 1; tail >= 0 && head < tail; tail--) {            if (A[tail] + A[head] <= w) {                head++;            }            res++;        }        if (tail == head)            res++;        return res;    }};