【面试题】 Maximum Number of Pairs with the Same Sum

1、 题目

You are given an array of integers. Your task is to create pairs of them, such that every created pair has the same sum. This sum is not specified, but the number of created pairs should be the maximum possible. Each array element may belong to one pair only. (给定一个整数数组。你的任务是:使用数组中的数创建一组数对(Pair),每对数的和(sum)都是相同的。这个和不被指定,但是数对的个数要尽可能的多。每个数组中的元素只能归属于一个数对。)

Write a function: 

class Solution {
    public int solution(int[] A);
}

that, given an array A consisting of N integers, returns the maximum possible number of pairs with the same sum. (参数是int数组A,返回数对的个数。)

Examples:

1. Given A = [1, 9, 8, 100, 2], the function should return 2. The pairs are (A[0], A[1]) and (A[2], A[4]); the sum of each pair is 10.  (A = [1, 9, 8, 100, 2]  返回值是2, 数对是(1,9) (8,2),sum = 10)

2. Given A = [2, 2, 2, 3], the function should return 1. Although, for instance, A[0]+A[1] = A[0]+A[2], the pairs (A[0], A[1]) and (A[0], A[2]) cannot exist at the same time, because they both contain a common element, A[0]. (A = [2, 2, 2, 3]  返回值是1 , )

3. Given A = [5, 5], the function should return 1.  (A = [5, 5] 返回值是1 )

Assume that:

  • N is an integer within the range [2..50];

  • each element of array A is an integer within the range [1..1,000].


2、 方法一:Brute Force

暴力解法:首先枚举数组A元素的两两组合。这样就得到所有可能的sum。用一个Map记录元素个数,Key是元素值,Value是元素值在A中的个数。在固定sum的前提下,利用这个Map完成配对儿。得到每种sum的Pair数。记录最大值即可。代码如下:

import java.util.*;

public class Solution {

    public static void main(String[] args) {
        Solution s = new Solution();
        System.out.println("[1, 9, 8, 50, 2] ->" + s.solution(new int[]{1, 9, 8, 50, 2}));
        System.out.println("[200, 200, 200, 300] ->" + s.solution(new int[]{200, 200, 200, 300}));
        System.out.println("[5, 5] ->" + s.solution(new int[]{5, 5}));
        System.out.println("[2,2,2,2] ->" + s.solution(new int[]{2, 2, 2, 2}));
    }

    public int solution(int[] A) {

        // 统计元素个数
        Map<Integer, Integer> valueCountMap = new HashMap<>();
        for (int i = 0; i < A.length; i++) {
            valueCountMap.put(A[i], valueCountMap.getOrDefault(A[i], 0) + 1);
        }

        int result = 0;

        // 枚举数组A中元素两两组合。先把sum固定下来。
        for (int i = 0; i < A.length - 1; i++) {
            for (int j = i + 1; j < A.length; j++) {
                Map<Integer, Integer> map = new HashMap<>(valueCountMap);
                map.put(A[i], map.get(A[i]) - 1);
                map.put(A[j], map.get(A[j]) - 1);
                int sum = A[i] + A[j];
                int pairCount = 1;
                Set<Integer> integers = map.keySet();
                for (Integer v : integers) {
                    // 挑选剩余没用完的元素
                    while (map.get(v) > 0) {
                        // 选取v,所以计数减1
                        map.put(v, map.get(v) - 1);
                        // 看是否存在另一个数
                        if (map.containsKey(sum - v) && map.get(sum - v) > 0) {
                            // 存在另一个数时,选取并计数减1
                            map.put(sum - v, map.get(sum - v) - 1);
                            pairCount += 1;
                        } else {
                            // 不存在另一个数,不能选取v
                            // 前面把计数减1了,这里要加回去
                            map.put(v, map.get(v) + 1);
                            break;
                        }
                    }
                }
                // 记录最大数
                result = Math.max(pairCount, result);
            }
        }
        return result;
    }
}

时间复杂度:O(N^3)

空间复杂度:需要O(N)的空间记录元素个数。

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

独立开发大本事

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值