日期:2014-05-20  浏览次数:20968 次

【算法比赛】在一个整数数组中寻找符合A+B=C的组合,使C为最大。看谁的算法最快。
刚才在C/C++版看到这个算法问题。。。就搬到这里大家一起玩玩。。。

说明在一个整数数组中寻找符合A+B=C的组合,使C为最大
A、B、C为数组三个不同的元素
数组的长度小于30000


输入、输出范例输入:{ 1, 4, 2, 3 }
输出:1+3=4

输入:{ 2, 3, 1, 4, 5 }
输出:2+3=5

输入:{ 5, 8, 3, 1, 2, 4, 4 }
输出:4+4=8

输入:{ 4, 4, 5, 0, 1, 2, 3, 8, 9, 9, 100 }
输出:0+9=9


测试代码:
C# code
private void button1_Click(object sender, EventArgs e) 
{
    #region 初始化数组
    int[] array = new int[arrayLength];
    Random random = new Random(1000); // 固定随机种子,使大家测试数据一致
    for (int i = 0; i < array.Length; i++)
        array[i] = random.Next(arrayLength * 10);
    #endregion 初始化数组

    int A, B, C;
    long tickCount = Environment.TickCount;
    Search(array, out A, out B, out C);
    Console.WriteLine("计算结果:A={0} B={1} C={2},耗时:{3}",
        A, B, C, Environment.TickCount - tickCount);
}

public void Search(int[] array, out int A, out int B, out int C)
{
    A = -1;
    B = -1;
    C = -1;
    /* TODO : 自由发挥 */
}


最优算法奖励100分,其他酌情散掉。

------解决方案--------------------
我是来收藏的
------解决方案--------------------
C# code
public void Search(int[] array, out int A, out int B, out int C)
        {
            A = -1;
            B = -1;
            C = -1;
            int[] all = new int[arrayLength * 10];
            for (int i = 0; i < array.Length; i++)
                all[array[i]]++;


            for (int j = all.Length-1; j > 0; j--)
            {
                if (all[j] == 0) continue;
                int num = j;
                int halfnum=num/2;
                if (num % 2 == 0)
                {
                    if (all[halfnum] >= 2)
                    {
                        A = B = halfnum;
                        C = j;
                        return;
                    }
                }

                for (int t = 1; t < halfnum; t++)
                {
                    if (all[t] > 0 && all[num - t] > 0)
                    {
                        A = t;
                        B = num - t;
                        C = num ;
                        return;
                    }
                }


            }

------解决方案--------------------
C# code

static public void Search(int[] array, out int A, out int B, out int C)
{
    A = -1;
    B = -1;
    C = -1;

    if( array == null || array.Length < 3) return;

    // O(n*log n)
    Array.Sort<int>(array);
    int maxNumber = array[ array.Length-1 ];
    bool hasZero = (array[0] == 0);

    unsafe
    {
        byte* masks = stackalloc byte[maxNumber+2];

        //if not Microsoft's CLR, DO initialize the allocated stack!
        //for (int i = 0; i < maxNumber + 2; i++) masks[i] = 0;

        for(int i=0; i<array.Length; i++)
        {
            masks[ array[i] ]++;
        }

        // O(n*n)
        for(int i=array.Length -1; i>=0; i--)
        {
            int sum = array[i];

            // special case
            if( hasZero && masks[sum] > 1 )
            {
                A = 0; B = sum; C = sum; return;
            }

            int halfSum = sum / 2;
            for(int j = i-1; j>0 && array[j] >= halfSum; j--)
            {
                if (masks[sum - array[j]] > 0)
                {
                    A = sum - array[j]; B = array[j]; C = sum;
                    if (A != B || masks[A] > 1) return;
                    else { A = B = C = -1; }
                }
            }
        }
    }
    // done
}