zoukankan      html  css  js  c++  java
  • 一道算法题,求更好的解法

    问题(阿里2010年实习):

     给定一个数t,以及n个整数,在这n个整数中找到相加之和为t的所有组合,例如t = 4n = 6,这6个数为[4, 3, 2, 2, 1, 1],这样输出就有4个不同的组合,它们的相加之和为44, 3+1, 2+2, and 2+1+1。请设计一个高效算法实现这个需求。

    下面,给出一种解法:

    代码
    #include <stdio.h>

    #define  LEN 20

    int path[LEN];
    int arr[LEN] = {11122344555888101010121212};

    void clearpath()
    {
        
    int i;
        
    for (i = 0; i < LEN; i++)
        {
            path[i] 
    = 0;
        }
    }
    void out_put()
    {
        
    int i;
        
    for (i = LEN-1; i >= 0; i--)
        {
            
    if(path[i] == 1)
                printf(
    " %d ", arr[i]);
        }
        printf(
    "\n");
    }

    /*算法:
    **q(n, t)表示从arr[0]...arr[n]中选出和为t的子集,则
    **q(n, t) = q(n-1, t-arr[n]) + q(n-1, t)
    */
    void q(int n, int t, int flag)
    {
         
    if(t < 0)
             
    return;

        path[n
    +1= flag;

        
    if(n == 0)
        {
            
    if(t == 0)
            {
                path[n] 
    = 0//不包含arr[0]
                out_put();
            }
            
    else if(arr[n] == t)
            {
                path[n] 
    = 1;//包含arr[0]
                out_put();
            }
        }
        
    else
        {
            q(n
    -1, t-arr[n], 1); //包含arr[n]
            q(n-1, t, 0); //不包含arr[n]
        }
    }

    void subsum(int len, int t)
    {
        q(len 
    - 1, t - arr[len], 1);
        q(len 
    - 1, t, 0);
    }
    int main()
    {
        
    int t = 20;
        clearpath();
        subsum(LEN 
    - 1, t);
        
    return 0;
    }

    该算法的时间复杂度为指数级(但实际情况应该好很多,与t相关),而且最大的问题在于,无法去掉重复的组合。求更好的解法。

  • 相关阅读:
    推荐一本SQL经典书籍
    准备升级包包版游戏大厅
    《博客园精华集软件工程分册》第三轮筛选结果
    (翻译)《Expert .NET 2.0 IL Assembler》 第八章 基本类型和签名(一)
    如何输入人名间的顿号
    推荐一个下名人传记电子书的好地方
    asp.net 2.0 中使用web.config存储数据库连接字符串
    Asp.Net小技巧之在client端调用server端事件:
    C#编码好习惯
    把ip转换成对应的城市名
  • 原文地址:https://www.cnblogs.com/hustcat/p/1735774.html
Copyright © 2011-2022 走看看