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相关),而且最大的问题在于,无法去掉重复的组合。求更好的解法。

  • 相关阅读:
    052-141
    052-140
    052-139
    052-138
    需要做笔记的页面
    日期总是显示1900/01/01 0:00:00
    延迟加载的树控件
    (简单)关于summary的注释
    江南检测
    fineui动态添加用户控件
  • 原文地址:https://www.cnblogs.com/hustcat/p/1735774.html
Copyright © 2011-2022 走看看