java 算法 求出结果的个数

题意:

算法题:有多少种结果
  题意:给出一个正整数数 n(n>=2),
  算出有多少种方式,可以使m1,m2,m3.....mn(1<=m1,m2,m3....mn<n)相加的结果为n,
  结果输出:并且输出结果个数每个方式和结果。
  结果样例:
  n=3:3 1+1+1=3,1+2=3 
  n=4: 3 1+1+1+1=4,1+1+2=4,1+3=4,2+2=4
  1+2+1 和1+1+2是相同的不允许同时出现

 

package com.junl.scott.consequence;

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

/*
 * 
 * 算法题:有多少种结果
 * 题意:给出一个正整数数 n(n>=2),
 * 算出有多少种方式,可以使m1,m2,m3.....mn(1<=m1,m2,m3....mn<n)相加的结果为n,
 * 结果输出:并且输出结果个数每个方式和结果。
 * 结果样例:
 * n=3:3 1+1+1=3,1+2=3
 * 
 * n=4: 3 1+1+1+1=4,1+1+2=4,1+3=4,2+2=4
 * 1+2+1 和1+1+2是相同的不允许同时出现
 */
public class MyConsequence
{
	public static void main(String[] args)
	{
		// 给定数字
		long start = System.currentTimeMillis();
		int number = 20;
		// 获取结果
		List<String> foramtList = MyConsequence.formatLists(MyConsequence.getResults(number));
		// List<String> foramtList = MyConsequence.getResults(number);
		// 定义变量
		// 设置返回结果类型
		System.out.println("当前数字:" + number);
		System.out.println("结果个数:" + foramtList.size());
		System.out.println("结果集:");
		// 循环读取
		for (String str : foramtList)
		{
			System.out.println(str);
		}
		long end = System.currentTimeMillis();
		System.out.println("程序运行时间:" + (end - start) + "毫秒");
	}

	/*
	 * 该方法为递归调用方法,在此没有判断参数小于2的情况
	 */
	private static List<String> getResults(int number)
	{
		List<String> typeLists = new ArrayList<String>();
		List<String> type = new ArrayList<String>();
		// 如果参数为2则只有1+1这种情况
		if (number == 2)
		{
			type.add("1+1");
		}
		// 如果不等于2
		else
		{
			// 首先获取两个数相加的和等于参数的情况
			for (int i = 1; i <= number / 2; i++)
			{
				type.add(i + "+" + (number - i));
			}
			// 递归调用,在这里有个问题是会有大量的重复数据,在后面要处理一下
			// 循环读取出所有可能的值
			for (int w = 1; w <= number / 2; w++)
			{
				typeLists = getResults(number - w);
				for (String str : typeLists)
				{
					type.add(w + "+" + str);
				}
			}
		}
		return type;
	}

	private static List<String> formatLists(List<String> results)
	{
		List<String> formatList = new ArrayList<String>();
		int j = 0;
		// 这个循环有点类似冒泡排序
		for (int i = 0; i < results.size() - 1; i++)
		{
			for (j = i + 1; j < results.size(); j++)
			{
				// 如果相同,则跳出这个循环,不保存数据
				if (formatList(results.get(i), results.get(j)))
				{
					break;
				}
			}
			// 如果到结束还没有找到相同的则加入
			if (j == results.size())
			{
				formatList.add(results.get(i));
			}
		}
		// 将最后一个加入,因为最后一个没有遍历,只是进行了比较
		formatList.add(results.get(results.size() - 1));
		return formatList;
	}

	private static boolean formatList(String str1, String str2)
	{
		// 长度不一样
		if (str1.length() != str2.length())
		{
			return false;
		}
		// 长度一样
		else
		{
			// 相等
			if (str1.equals(str2))
			{
				return true;
			}

			Stack<Character> stack1 = new Stack<Character>();
			Stack<Character> stack2 = new Stack<Character>();
			for (int i = 0; i < str1.length(); i++)
			{
				if ('+' != str1.charAt(i))
					stack1.push(str1.charAt(i));
				if ('+' != str2.charAt(i))
					stack2.push(str2.charAt(i));
			}
			for (int j = 0; j <= stack2.size(); j++)
			{
				for (int t = stack2.size() - 1; t >= 0; t--)
				{
					if (stack1.lastElement() == (stack2.get(t)))
					{
						stack1.pop();
						stack2.remove(t);
						t = stack2.size() - 1;
						j = 0;
						break;
					}
				}
			}
			if (stack1.isEmpty() && stack2.isEmpty())
			{
				return true;
			}
		}
		return false;
	}
}


我的这个方式很耗时间,我运行20的时候需要47635毫秒,如果数字大一点的话,肯定会内存溢出,所以测试的时候要小心。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值