在一个正整数可重复的数组中按顺序取若干数,使结果等于目标数

本文介绍了一种算法,用于解决将给定数量的元素分配到不同区组的问题,根据给定的区组长度列表找到满足条件的元素组合。通过实例展示了如何在不同长度的区组中找到符合条件的结果,并记录了每个成功的匹配过程。

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

数:8=====区组:[6,4,6,4,6,4]=====结果:[4, 4]
数:22====区组:[6,2,4,4,8]======结果:[6, 4, 4, 8]
数:12====区组:[2,6,2,6,4,4]=====结果:[2, 6, 4]

 栈 :先进后出

 数:8=====区组:[6,4,6,4,6,4]

6入栈

6出栈

4入栈

4入栈

结果 [4, 4]  (第2个4和第4个4 ,下标 :1、3)

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

import com.google.common.collect.Lists;
import com.google.common.primitives.Ints;

public class BlindTest {

/*	public static void main(String[] args) {
		
		List<String> a = null;
		name(a);
		
		System.out.println(a);
	}
	
	public static Integer name(List<String> a) {
		a = Lists.newArrayList();
		a.add("a");
		
		
		 * 8个 基本数据类型 : 
		 * 整型    :byte short int long
		 * 字符型:char
		 * 浮点型:float double
		 * 布尔型:boolean
		 
		
		// 基本数据类型 没有 null
		// Type mismatch: cannot convert from null to int
		
		
		// Integer 是 int 的包装类
		// 引用数据类型 有 null
		new String();
		
		return null;
		
	}*/
	
	public static void main(String[] args) throws InterruptedException {
		List<Integer> blockLengthList = Lists.newArrayList();
		blockLengthList.add(4);
		blockLengthList.add(6);
		blockLengthList.add(2);
		blockLengthList.add(2);
		blockLengthList.add(6);
		blockLengthList.add(9);
		blockLengthList.add(3);
		blockLengthList.add(6);
		blockLengthList.add(3);

		Collections.reverse(blockLengthList);
//		3*4 , 6*3 , 9*2
//		
//		12 + 18 +18 = 48
//		
//		
//		3 6 9 3 6 9 3 6 3    01
//		
//		3 6 9 3 6 9 3 6 3    02
		
		
		
		name(blockLengthList, 8);
		
	
		name(Ints.asList(new int[]{2,6,2,6,4,4,6}), 12);
		name(Ints.asList(new int[]{2,4,4,4,6}), 8);
		name(Ints.asList(new int[]{2,6,6,6,6,6,6}), 36);
		name(Ints.asList(new int[]{6,2,6,6,6,6,6}), 36);
		name(Ints.asList(new int[]{6,6,2,6,6,6,6}), 36);
		name(Ints.asList(new int[]{6,6,6,2,6,6,6}), 36);
		name(Ints.asList(new int[]{6,6,6,6,2,6,6}), 36);
		name(Ints.asList(new int[]{6,6,6,6,6,2,6}), 36);
		name(Ints.asList(new int[]{6,6,6,6,6,6,2}), 36);
		
		name(Ints.asList(new int[]{6,4,6,4,6,4}), 8);
		name(Ints.asList(new int[]{6,2,4,4,8}), 22);
		name(Ints.asList(new int[]{2,6,2,6,4,4}), 12);
		name(Ints.asList(new int[]{2,6,2,6,4,4}), 14);
		name(Ints.asList(new int[]{4,6,2,4,6,2}), 24);
		name(Ints.asList(new int[]{4,6,2,4,6,2}), 18);
		name(Ints.asList(new int[]{4,6,2,4,6,2}), 8);
		name(Ints.asList(new int[]{2,6,2,6,4,4,6}), 14);
		name(Ints.asList(new int[]{2,6,4,6,6}), 14);
		name(Ints.asList(new int[]{4,6,2}), 8);
		name(Ints.asList(new int[]{2,2,6,6,6}), 18);
		name(Ints.asList(new int[]{2,2,2,10,2,30}), 40);
		name(Ints.asList(new int[]{2,2,2,10,2}), 40);
		name(Ints.asList(new int[]{2,2,2,8,4}), 24);
		name(Ints.asList(new int[]{8,8}), 24);
		name(Ints.asList(new int[]{8,2,2,2,8}), 16);
		name(Ints.asList(new int[]{2,2,2,8,4,4}), 16);
		name(Ints.asList(new int[]{2,2,2,2,6,6,4,6,4,40,40,40}), 120);
		name(Ints.asList(new int[]{100,100,100,100,100,2,100,100,2,100,100,4,100,6,100,2,100}), 16);
//		List<Integer> array2 = name(blockLengthList, 20);
//		System.out.println("result:" + array2);
//		List<Integer> array3 = name(blockLengthList, 18);
//		System.out.println("result:" + array3);
//		List<Integer> array4 = name(blockLengthList, 16);
//		System.out.println("result:" + array4);
//		
//		
//		List<Integer> array5 = name(blockLengthList, 30);
//		System.out.println("result:" + array5);
		
//				成功      ==例数:8====区组:[3,6,3,9,6,2,2,6,4]====元素下标:[0, 2, 5]=====结果:[3, 3, 2]====总和:8
//				成功      ==例数:12====区组:[2,6,2,6,4,4,6]====元素下标:[0, 1, 4]=====结果:[2, 6, 4]====总和:12
//				成功      ==例数:8====区组:[2,4,4,4,6]====元素下标:[0, 4]=====结果:[2, 6]====总和:8
//				成功      ==例数:36====区组:[2,6,6,6,6,6,6]====元素下标:[1, 2, 3, 4, 5, 6]=====结果:[6, 6, 6, 6, 6, 6]====总和:36
//				成功      ==例数:36====区组:[6,2,6,6,6,6,6]====元素下标:[0, 2, 3, 4, 5, 6]=====结果:[6, 6, 6, 6, 6, 6]====总和:36
//				成功      ==例数:36====区组:[6,6,2,6,6,6,6]====元素下标:[0, 1, 3, 4, 5, 6]=====结果:[6, 6, 6, 6, 6, 6]====总和:36
//				成功      ==例数:36====区组:[6,6,6,2,6,6,6]====元素下标:[0, 1, 2, 4, 5, 6]=====结果:[6, 6, 6, 6, 6, 6]====总和:36
//				成功      ==例数:36====区组:[6,6,6,6,2,6,6]====元素下标:[0, 1, 2, 3, 5, 6]=====结果:[6, 6, 6, 6, 6, 6]====总和:36
//				成功      ==例数:36====区组:[6,6,6,6,6,2,6]====元素下标:[0, 1, 2, 3, 4, 6]=====结果:[6, 6, 6, 6, 6, 6]====总和:36
//				成功      ==例数:36====区组:[6,6,6,6,6,6,2]====元素下标:[0, 1, 2, 3, 4, 5]=====结果:[6, 6, 6, 6, 6, 6]====总和:36
//				成功      ==例数:8====区组:[6,4,6,4,6,4]====元素下标:[1, 3]=====结果:[4, 4]====总和:8
//				成功      ==例数:22====区组:[6,2,4,4,8]====元素下标:[0, 2, 3, 4]=====结果:[6, 4, 4, 8]====总和:22
//				成功      ==例数:12====区组:[2,6,2,6,4,4]====元素下标:[0, 1, 4]=====结果:[2, 6, 4]====总和:12
//				成功      ==例数:14====区组:[2,6,2,6,4,4]====元素下标:[0, 1, 2, 4]=====结果:[2, 6, 2, 4]====总和:14
//				成功      ==例数:24====区组:[4,6,2,4,6,2]====元素下标:[0, 1, 2, 3, 4, 5]=====结果:[4, 6, 2, 4, 6, 2]====总和:24
//				成功      ==例数:18====区组:[4,6,2,4,6,2]====元素下标:[0, 1, 2, 3, 5]=====结果:[4, 6, 2, 4, 2]====总和:18
//				成功      ==例数:8====区组:[4,6,2,4,6,2]====元素下标:[0, 2, 5]=====结果:[4, 2, 2]====总和:8
//				成功      ==例数:14====区组:[2,6,2,6,4,4,6]====元素下标:[0, 1, 2, 4]=====结果:[2, 6, 2, 4]====总和:14
//				成功      ==例数:14====区组:[2,6,4,6,6]====元素下标:[0, 1, 3]=====结果:[2, 6, 6]====总和:14
//				成功      ==例数:8====区组:[4,6,2]====元素下标:[1, 2]=====结果:[6, 2]====总和:8
//				成功      ==例数:18====区组:[2,2,6,6,6]====元素下标:[2, 3, 4]=====结果:[6, 6, 6]====总和:18
//				成功      ==例数:40====区组:[2,2,2,10,2,30]====元素下标:[3, 5]=====结果:[10, 30]====总和:40
//				失败!!      ==例数:40====区组:[2,2,2,10,2]====元素下标:[]=====结果:[]====总和:0
//				失败!!      ==例数:24====区组:[2,2,2,8,4]====元素下标:[]=====结果:[]====总和:0
//				失败!!      ==例数:24====区组:[8,8]====元素下标:[]=====结果:[]====总和:0
//				成功      ==例数:16====区组:[8,2,2,2,8]====元素下标:[0, 4]=====结果:[8, 8]====总和:16
//				成功      ==例数:16====区组:[2,2,2,8,4,4]====元素下标:[0, 1, 3, 4]=====结果:[2, 2, 8, 4]====总和:16
//				成功      ==例数:120====区组:[2,2,2,2,6,6,4,6,4,40,40,40]====元素下标:[9, 10, 11]=====结果:[40, 40, 40]====总和:120
//				成功      ==例数:16====区组:[100,100,100,100,100,2,100,100,2,100,100,4,100,6,100,2,100]====元素下标:[5, 8, 11, 13, 15]=====结果:[2, 2, 4, 6, 2]====总和:16
	}

	
	
	/**
	 * 
	 * @param blockLengthList 可用的 区组长度的  倒序的 集合
	 * @param numChange 需要的数量
	 * @return
	 * @throws InterruptedException 
	 */
	public static List<Integer> name(List<Integer> blockLengthList, int numChange) throws InterruptedException {
		// 末尾输出用
		int num = numChange;
		
		// 步骤输出
//		boolean isOutPrintln = true;
		boolean isOutPrintln = false;
		
		// 结果(区组所在数组的位置)
		Stack<Integer> stack = new Stack<Integer>();
		
		int index = 0;
		while(numChange!=0) {
			
//			升格
			if(isOutPrintln)Thread.sleep(100);
			
			if(isOutPrintln)System.out.println(" 开始匹配=====================================================index:"+index);
			if(isOutPrintln)System.out.println(" 栈内元素"+stack);
			// 是否回滚
			boolean isRollback = true;
			for (int i = index; i<blockLengthList.size(); i++) {
				int blockLength = blockLengthList.get(i);
				
				if(numChange>=blockLength) {
					numChange-=blockLength;
					stack.push(i);
					index = i+1;
					isRollback = false;
					if(isOutPrintln)System.out.println(" 匹配着了=============index:"+i+"=================="+blockLength+"还剩 "+numChange);
					break;
				}
			}
			
			// 回滚
			if(isRollback){
				if(stack.isEmpty()) {
					index++;
				}else {
					Integer pop = stack.pop();
					numChange+=blockLengthList.get(pop);
					index = pop+1;
				}
				
				if(index>blockLengthList.size()) {
					break;
				}
				
				if(isOutPrintln)System.out.println("  回滚了====================index:"+index+"还剩 "+numChange+"不符合的元素"+blockLengthList.subList(index, blockLengthList.size()));
				if(isOutPrintln)System.out.println(" 栈内元素"+stack);

			}
			
//			if(isRollback){
//				Integer pop;
//				if(stack.isEmpty()) {
//					pop = index;
//					index++;
//				}else {
//					pop = stack.pop();
//					numChange+=blockLengthList.get(pop);
//					index = pop+1;
//				}
//				
//				if(isOutPrintln)System.out.println("  回滚了====================index:"+index+"还剩 "+numChange+"不符合的元素"+blockLengthList.subList(pop+1, blockLengthList.size()));
//				if(isOutPrintln)System.out.println(" 栈内元素"+stack);
//				
//				boolean isRollback2 = true;
//				
//				for (int i = pop+1; i<blockLengthList.size(); i++) {
//					int blockLength = blockLengthList.get(i);
//					
//					if(numChange>=blockLength) {
//						numChange-=blockLength;
//						stack.push(i);
//						index = i+1;
//						if(isOutPrintln)System.out.println(" 匹配着了=============index:"+index+"=================="+blockLength+"还剩 "+numChange);
//						isRollback2 = false;
//						break;
//					}
//				}
//				
//				if(isRollback2){
//					if(!stack.isEmpty()) {
//						pop = stack.pop();
//						numChange+=blockLengthList.get(pop);
//					}
//					index++;
//					if(isOutPrintln)System.out.println("  又回滚了===================index:"+index+"还剩 "+numChange);
//					if(isOutPrintln)System.out.println("index:"+index+" 栈内元素"+stack);
//				}
//				
//			}
		}
		List<Integer> result = Lists.newArrayList();
		int sum = 0;
		
		for (Integer integer : stack) {
			sum+=blockLengthList.get(integer);
			result.add(blockLengthList.get(integer));
		}
		
		
		System.out.print((numChange==0?"成功":"失败!!"));
		
		System.out.print("      ==例数:"+num+"====区组:[");
		
		for (int i = 0; i < blockLengthList.size(); i++) {
			if(i!=0)System.out.print(",");
			Thread.sleep(1);
			if(stack.contains(i)) {
				System.err.print(blockLengthList.get(i));
			}else {
				System.out.print(blockLengthList.get(i));
			}
			Thread.sleep(1);
		}
		
		System.out.println("]====元素下标:"+stack+"=====结果:"+result+"====总和:"+sum+"");
		
		if(num!=sum) {
			return null;
		}
		
		
//		System.out.println((num==sum?"成功":"失败!!")+"      ==例数:"+num+"====区组"+blockLengthList+"====元素下标:"+stack+"=====结果:"+result+"====总和:"+sum+"");
		return new ArrayList<Integer>(stack);
	}
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值