Appearance
数组元素拆分到多个数组
需求
一个数组中有若干个元素,需要将这若干个元素拆分到 n 个数组中, 每个数组中的元素数量尽量均等。
思路
考虑两种情况:数组元素可以被均等拆分和数组元素不能被均等拆分。
数组元素可以被均等拆分
第一种情况好办,目标数组元素数量 = 原数组元素数量 / 目标数组个数 count = sourceList / n
。假设初始下标 i 为 0,循环 n - 1 次,则有目标数组 targetList[i]
的元素为 sourceList[i * count]
到 sourceList[((i + 1) * count) - 1]
之间的元素。
数组元素不能被均等拆分
这一种情况就有些复杂了,因为拆分到目标数组的元素并不均等,所有会有剩余的元素。假设剩余元素数量为 remainder,偏移量 offset 为 0,则有目标数组 targetList[i]
的元素为 sourceList[i * count + offset]
到 sourceList[((i + 1) * count + (offset + 1)) - 1]
之间的元素。
实现
Java 中的 List
接口有一个 subList
方法,可以便捷的帮我们截取指定区间的元素。
java
/**
* @param fromIndex 要截取的起始索引
* @param toIndex 要截取的结束索引(不包含此索引)
* @return 返回列表中指定范围的视图(对它的修改会影响到原有的 List,同样,对 List 的修改也会影响到 它)
*/
List<E> subList(int fromIndex, int toIndex)
java
/**
* 原数组拆分成指定数量的数组
* @param sourceList 原数组
* @param n 指定数量
* @param <T> 数组元素类型
* @return 指定数量的数组
*/
private static <T> List<List<T>> averageAssignList(List<T> sourceList, int n) {
ArrayList<List<T>> lists = new ArrayList<>();
int size = sourceList.size();
int count = size / n;
int remainder = size % n;
int offset = 0;
for (int i = 0; i < n; i++) {
List<T> list;
if (remainder > 0) {// 数组元素不能被均等拆分
list = sourceList.subList(i * count + offset, (i + 1) * count + (offset + 1));
offset++;
remainder--;
} else {// 数组元素可以被均等拆分
list = sourceList.subList(i * count + offset, (i + 1) * count + offset);
}
lists.add(list);
}
return lists;
}
测试
java
public static void main(String[] args) {
ArrayList<Integer> integers = new ArrayList<>();
integers.add(1);
integers.add(2);
integers.add(3);
integers.add(4);
integers.add(5);
integers.add(6);
integers.add(7);
integers.add(8);
List<List<Integer>> lists = averageAssignList(integers, 3);
System.out.println("数组元素不可以被均等拆分:" + lists);
System.out.println("--------------------");
integers.add(9);
List<List<Integer>> lists1 = averageAssignList(integers, 3);
System.out.println("数组元素可以被均等拆分:" + lists1);
}
数组元素不可以被均等拆分:[[1, 2, 3], [4, 5, 6], [7, 8]]
--------------------
数组元素可以被均等拆分:[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
完整代码
java
package study.helloworld.something4j._2020._04._16;
import java.util.ArrayList;
import java.util.List;
/**
* 数组元素拆分到多个数组
*/
public class AverageAssign4Array {
public static void main(String[] args) {
ArrayList<Integer> integers = new ArrayList<>();
integers.add(1);
integers.add(2);
integers.add(3);
integers.add(4);
integers.add(5);
integers.add(6);
integers.add(7);
integers.add(8);
List<List<Integer>> lists = averageAssignList(integers, 3);
System.out.println("数组元素不可以被均等拆分:" + lists);
System.out.println("--------------------");
integers.add(9);
List<List<Integer>> lists1 = averageAssignList(integers, 3);
System.out.println("数组元素可以被均等拆分:" + lists1);
}
/**
* 原数组拆分成指定数量的数组
* @param sourceList 原数组
* @param n 指定数量
* @param <T> 数组元素类型
* @return 指定数量的数组
*/
private static <T> List<List<T>> averageAssignList(List<T> sourceList, int n) {
ArrayList<List<T>> lists = new ArrayList<>();
int size = sourceList.size();
int count = size / n;
int remainder = size % n;
int offset = 0;
for (int i = 0; i < n; i++) {
List<T> list;
if (remainder > 0) {// 数组元素不能被均等拆分
list = sourceList.subList(i * count + offset, (i + 1) * count + (offset + 1));
offset++;
remainder--;
} else {// 数组元素可以被均等拆分
list = sourceList.subList(i * count + offset, (i + 1) * count + offset);
}
lists.add(list);
}
return lists;
}
}