CombinationToSum.java

本文介绍了一种组合求和算法,该算法旨在找出从1到n的整数序列中所有可能的组合,使得这些组合的元素之和等于给定的目标值m。通过递归和迭代两种方法实现,并给出了具体实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >




package test;

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

/**
 * http://bylijinnan.iteye.com/blog/1347441
 * 
 * @author ZengWenFeng
 *
 */
public class CombinationToSum
{
	/*
	 * 第21 题 2010 年中兴面试题 编程求解: 输入两个整数 n 和 m ,从数列 1 , 2 , 3.......n 中随意取几个数 , 使其和等于 m ,
	 * 要求将其中所有的可能组合列出来 . two solutions permutation01:Recursion.easy to write and read-->pick n or
	 * not,haha permutation02:put n,then put n-1...if bigger,remove;if smaller,keep putting;if
	 * ok,output.
	 */
	public static void main(String[] args)
	{
		CombinationToSum cts = new CombinationToSum();
		//permutation01(int sum,int n)  
		cts.permutation01(10, 10);
		System.out.println("===========");
		cts.permutation02(10, 6);
	}

	/*
	 * Recursion.use Stack<Integer> we can use ArrayList,too. private List<Integer> list=new
	 * ArrayList<Integer>(); list.add(n); list.remove(list.indexOf(n));
	 */
	private Stack<Integer> stack = new Stack<Integer>();

	public void permutation01(int sum, int n)
	{
		if (n <= 0 || sum <= 0)
			return;
		if (sum == n)
		{
			printStack(stack);
			System.out.print(n);
			System.out.println();
		}
		stack.add(n);
		permutation01(sum - n, n - 1);
		stack.pop();
		permutation01(sum, n - 1);
	}

	public void permutation02(int sum, int n)
	{
		if (n <= 0 || sum <= 0)
			return;
		for (int i = n; i > 0; i--)
		{
			if (i == sum)
			{
				System.out.println(i);
				continue;
			}
			List<Integer> list = new ArrayList<Integer>();
			list.add(i);
			for (int j = i - 1; j > 0;)
			{
				list.add(j);
				int ret = isOK(list, sum);
				if (ret < 0)
				{
					j--;
				}
				if (ret == 0)
				{
					printList(list);
					System.out.println();
					j = list.get(1) - 1;//now we go back and make the second element smaller  
					list.clear();
					list.add(i);
				}
				if (ret > 0)
				{
					list.remove(list.size() - 1);//too large,remove the last element  
					j--;
				}
			}
		}
	}

	// whether the sum of list element equals to sum or not  
	public static int isOK(List<Integer> list, int sum)
	{
		int re = 0;
		int total = 0;
		for (int each : list)
		{
			total += each;
		}
		if (total > sum)
			re = 1;
		if (total < sum)
			re = -1;
		return re;

	}

	public void printStack(Stack<Integer> stack)
	{
		/*
		 * while(!stack.isEmpty()){ int temp=stack.pop(); System.out.print(temp+" "); }
		 */
		//don't remove the elements in stack  
		for (Integer each : stack)
		{
			System.out.print(each + " ");
		}
	}

	public void printList(List<Integer> list)
	{
		for (int each : list)
		{
			System.out.print(each + " ");
		}
	}

}

10
9 1
8 2
7 3
7 2 1
6 4
6 3 1
5 4 1
5 3 2
4 3 2 1
===========
6 4 
6 3 1 
5 4 1 
5 3 2 
4 3 2 1 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

spencer_tseng

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

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

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

打赏作者

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

抵扣说明:

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

余额充值