树、二叉树(完全二叉树、满二叉树)概念图解
二叉树:每个结点最多两个子节点
满二叉树:除根节点和子节点外,其他结点的子节点都是2
完全二叉树:各个结点的位置和满二叉树结点的位置相同,只是比满二叉树的结点少
**算法最少分组法-将数组arr中的数字分组,要求各个分组中数字之和小于等于k,求最小分组数的情况,默认arr中每个数均小于k.**
1 package com.xxx.utils;
2
3 import com.google.common.primitives.Ints;
4
5 import java.util.*;
6
7 public class ArrayGroupUtils {
8
9 public static void main(String[] args) {
10 // int[] arr = {5, 6, 4, 8, 7, 1, 2, 3};//4 5 6 7 8
11 int[] arr = {1, 2, 5, 6, 6, 9, 10, 17, 18, 2, 8, 20};
12 List<List<Integer>> lists = minGroup(arr, 30);
13 for (List<Integer> list : lists) {
14 System.out.println(list);
15 }
16 }
17
18
19 /**
20 * 最少分组法-将数组arr中的数字分组,要求各个分组中数字之和小于等于k,求最小分组数的情况,默认arr中每个数均小于k
21 * <p>
22 * 第一步:排序,将数组先折腾成有序的(升序)。
23 * <p>
24 * 第二步:从数组第一个开始计算和,超过K了,这些就分一组。然后开始计算下一组的和,最后直到数组的末尾。
25 * <p>
26 * 第三步:现在每一组i都有一个到K距离的D[i]。现在除去第一个分组外将所有其它分组的D[i]进行排序。
27 * 从第一个分组中最大的数开始扫描,将它放置到能够容纳这个数的,距离K的D[i]最小的其它分组中。这个过程我称为分裂。分裂完成后要重新排序。
28 * <p>
29 * 终止条件:如果第一个分组全部分裂完成了,则再这样分裂第二个分组。直到某个分组不能分裂为止。
30 *
31 * @param arr
32 * @param k
33 */
34 public static List<List<Integer>> minGroup(int[] arr, int k) {
35 //获取升序的list
36 List<Integer> list = Ints.asList(arr);
37 Collections.sort(list);
38
39 //子list
40 List<List<Integer>> subList = new ArrayList<>();//-->List<Map<Integer,List> >
41 List<List<Integer>> resultList = new ArrayList<>();//返回结果
42
43
44 Integer temp = 0;
45 List<Integer> tempList = new ArrayList<>();
46
47
48 for (Integer integer : list) {
49
50 if ((temp + integer) < k) {
51 tempList.add(integer);
52 temp += integer;
53 } else if ((temp + integer) > k) {
54 temp = integer;
55 subList.add(tempList);
56 tempList = new ArrayList<>();
57 tempList.add(integer);
58 } else {
59 tempList.add(integer);
60 temp = 0;
61 subList.add(tempList);
62 tempList = new ArrayList<>();
63 }
64
65
66 }
67 subList.add(tempList);//加上最后一个数
68
69
70 for (int m = 0; m < subList.size(); m++) {
71 division(subList, resultList, k, m);
72 }
73
74 //处理sublist中为0的元素
75 List<List<Integer>> handZeroEleList = handZeroEle(subList);
76
77 return handZeroEleList;
78
79
80 }
81
82
83 private static void division(List<List<Integer>> subList, List<List<Integer>> resultList, int k, int m) {
84
85 /*生成D[i]:List的map按D[i]升序(除了第一个分组)*/
86 List<Map<Integer, List>> mapList = getSortedList(subList, k, m);
87
88 //遍历第一个分组下的所有元素
89 List<Integer> subList1 = subList.get(m);
90 Collections.reverse(subList1);
91
92 for (int n = 0; n < subList1.size(); n++) {
93 Integer integer = subList1.get(n);
94 for (int j = 0; j < mapList.size(); j++) {
95 Map<Integer, List> listMap = mapList.get(j);
96 Integer diTemp = getFirstKey(listMap);
97 List<Integer> listTemp = getFirstValue(listMap);
98 if (integer > diTemp) {//不能放进去,则比较下一个分组
99 continue;
100 } else {//正好能放进去,则重新进行排序-->继续循环
101 //往里加
102 listMap.remove(diTemp);
103 diTemp -= integer;
104 listTemp.add(integer);
105 listMap.put(diTemp, listTemp);
106
107 //往第一个分组里删除
108 //it.remove();
109 // integer = 0;
110 subList1.set(n, 0);
111
112 sortByCustom(mapList);
113 break;
114
115 }
116 }
117 }
118 resultList.add(subList1);
119
120 }
121
122
123 /**
124 * 获取除去第一个分组外将所有其它分组按D[i]进行排序
125 *
126 * @param subList
127 * @param k
128 * @return
129 */
130 private static List<Map<Integer, List>> getSortedList(List<List<Integer>> subList, int k, int m) {
131 List<Map<Integer, List>> mapList = new ArrayList<>();
132 for (int i = m + 1; i < subList.size(); i++) {
133 Map<Integer, List> tempMap = new HashMap<>();
134 tempMap.put(k - listSum(subList.get(i)), subList.get(i));
135 mapList.add(tempMap);
136 }
137 sortByCustom(mapList);
138 return mapList;
139 }
140
141
142 /**
143 * 排序
144 *
145 * @param mapList
146 * @return
147 */
148 private static void sortByCustom(List<Map<Integer, List>> mapList) {
149 Collections.sort(mapList, new Comparator<Map<Integer, List>>() {
150 @Override
151 public int compare(Map<Integer, List> o1, Map<Integer, List> o2) {
152 if (getFirstKey(o1) > getFirstKey(o2)) {
153 return 1;
154 }
155 if (getFirstKey(o1) == getFirstKey(o2)) {
156 return 0;
157 }
158 return -1;
159 }
160 });
161 }
162
163
164 /**
165 * 求数组和
166 *
167 * @param arr
168 * @return
169 */
170 public static int arraySum(int[] arr) {
171 int sum = 0;
172 for (int i : arr) {
173 sum += i;
174 }
175 return sum;
176 }
177
178 /**
179 * 求list<integer>和
180 *
181 * @param list
182 * @return
183 */
184 public static Integer listSum(List<Integer> list) {
185 Integer sum = 0;
186 for (Integer integer : list) {
187 sum += integer;
188 }
189 return sum;
190 }
191
192
193 /**
194 * 获取map中第一个key值
195 *
196 * @param map 数据源
197 * @return
198 */
199 private static Integer getFirstKey(Map<Integer, List> map) {
200 Integer obj = null;
201 for (Map.Entry<Integer, List> entry : map.entrySet()) {
202 obj = entry.getKey();
203 if (obj != null) {
204 break;
205 }
206 }
207 return obj;
208 }
209
210
211 /**
212 * 获取map中第一个数据值
213 *
214 * @param map 数据源
215 * @return
216 */
217 private static List getFirstValue(Map<Integer, List> map) {
218 List obj = null;
219 for (Map.Entry<Integer, List> entry : map.entrySet()) {
220 obj = entry.getValue();
221 if (obj != null) {
222 break;
223 }
224 }
225 return obj;
226 }
227
228
229 /**
230 * 将[0, 6, 6, 5, 0, 0]
231 * [0, 0, 17, 10]
232 * [2, 1, 9, 18]中的0去除掉
233 *
234 * @param subList
235 */
236 private static List<List<Integer>> handZeroEle(List<List<Integer>> subList) {
237 List<List<Integer>> resultList = new ArrayList<>();
238 for (List<Integer> integers : subList) {
239 List<Integer> list = new ArrayList<>();
240 for (Integer integer : integers) {
241 if (integer != 0) {
242 list.add(integer);
243 }
244 }
245 if (list.size() > 0) {
246 resultList.add(list);
247 }
248
249 }
250 return resultList;
251 }
252
253 }