一道算法题,求更好的解法

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

posted @   YY哥  阅读(3888)  评论(18编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
历史上的今天:
2009-05-14 字节对齐算法
点击右上角即可分享
微信分享提示