给定一个数组,查找数组中 任意个数相加大于等于指定数字 且个数最小,相加后最接近指定数字的组合。
优先个数,再考虑最接近
如:1, 2, 3, 4
目标数字:6
结果:2,4
感谢楼上两位,自己解决了,经过一些简单测试,能够满足需求,查询速度也还可以,附代码。
private static List<int> SearchItems(int[] array, int target) { List<int> list = new List<int>(); Array.Sort(array); int item = array.FirstOrDefault(m => m >= target); if (item != 0) { list.Add(item); return list; } int digit = array.Length; int cursor = 0; for (int m = 1; m <= array.Length; m++) { int tempCursor = 0; bool flag = true; int tempDigit = 0; List<int> tempGroup = new List<int>(); for (int i = array.Length - m; i >= 0; i--) { if (i > 0) { if (tempCursor + array[i - 1] >= target) { continue; } } tempDigit++; tempCursor += array[i]; tempGroup.Add(array[i]); if (tempCursor >= target) { if (tempDigit <= digit) { if (cursor == 0 || tempCursor < cursor) { list = tempGroup; cursor = tempCursor; } } else { flag = false; } digit = tempDigit; break; } if (i == 0) { flag = false; } } if (!flag) { break; } } return list; }
@李丶GuanYao: 思路不错,但还是有BUG,目标数字是最大数的多倍+n时,最大数字重复拿到。
数组为1, 4, 5, 7, 17, 18, 25,目标数字35,最优应是17,18而不应是25,17
取出了所以的,明天有时间再优化 int[] arr={1,2,3}; int num=2; List<string> strList = new List<string>(); for (int i = 0; i < arr.Count(); i++) { int all = arr[i]; String str = arr[i] + ","; for (int j = 0; j < arr.Count(); j++) { all += arr[j]; str += arr[j] + ","; if (all>=num) { strList.Add(str); } } }
不是要所有的哦,是要个数最少,且相加后最接近的组合。
考虑一下性能
。。。而且你这是在找所有组合。。。而且是有重复的。。。
@烽火情怀: 本来想实现一个复杂的为N的,下午测试的适合不行,目前就这样了,明天有时间加上
说一下思路:
1、对数组排序;
2、假设制定的数是a,则取1个数、取2个数、取3个数......取n个数,找大于等于a的集合;
不一定对,哎,我是来接分的
第2条复杂度就不会低了
static void Main(string[] args) { var array = new int[]{1, 2, 3, 4}; List<int> outArray=new List<int>(); var targetNumber = 10; Test(array, targetNumber,outArray); Console.WriteLine(string.Join(",",outArray)); Console.ReadKey(); } public static void Test(int[] array,int targetNumber,List<int> outArray ) { for (int i = 0; i < array.Count(); i++) { if (array[i]+ outArray.Sum() >= targetNumber) { outArray.Add(array[i]); return; } } var maxNumber = array.Max(); outArray.Add(maxNumber); Test(array, targetNumber, outArray); }
数字重复取出来了~递归效率太差。不过还是非常感谢
@烽火情怀: 好像不用递归的话.想不出别的好办法...因为传进来的数组和你的目标值可能相差很大.. 这样程序中很难控制到底循环数组多少次.
@李丶GuanYao: 嗯。最终写出的方法已经写在下边了,可以参考一下。
数组里面的元素有没有重复?
我觉得可以先排序,然后取目标数的中间值,根据中间值的情况沿着两边拿一下就行了。也就转化成了排序问题。在排序的时候可以直接定位中间值的位置。没写代码试过,去中间值以后分几种情况,比如目标数不是偶数,中间值在两边,在中间,分类取一下。
如果想找所有组合 要怎么写呢? 不会写这些计算的代码....