我正在尝试创建一个方法,使两个数组交叉重复。
示例:{1,2,5,4,1,3} and {1,2,1} -> {1,1,2}.
我有一个交叉但没有重复的方法。
public int[] findSameElements(int[] p1, int[] p2) {
int count = 0;
for (int i = 0; i < p1.length; i++) {
for (int j = 0; j < p2.length; j++) {
if (p1[i] == p2[j]) {
count++;
break;
}
}
}
int[] result = new int[count];
count = 0;
for (int i = 0; i < p1.length; i++) {
for (int j = 0; j < p2.length; j++) {
if (p1[i] == p2[j]) {
result[count++] = p1[i];
break;
}
}
}
return result;
}
如何在不使用Arrays.*
或List.*
的情况下添加重复内容?
答案 0 :(得分:5)
请尝试以下功能:
public int[] findSameElements(int[] p1, int[] p2)
{
int count = 0;
bool[] choosen = new bool[p2.length];
for (int i = 0; i < p1.length; i++)
{
for (int j = 0; j < p2.length; j++)
{
if (!choosen[j] && p1[i] == p2[j])
{
choosen[j] = true;
count++;
break;
}
}
}
int[] result = new int[count];
count = 0;
for (int i = 0; i < p2.length; i++)
{
if (choosen[i])
{
result[count] = p2[i];
count++;
}
}
return result;
}
如果有必要,您还应该应用排序,此解决方案具有O(N ^ 2)复杂度。 也可能使O(NLogN)复杂化。
答案 1 :(得分:2)
您可以构建histogram(将表示为Map<Integer,Integer>
)并且:
请注意,此解决方案为O(n+m)
时间(平均大小写)和O(min{n,m})
空间。
代码示例(使用List<T>
代替数组 - 但当然可以轻松修改):
private static <T> Map<T,Integer> populateHistogram(List<T> list) {
Map<T,Integer> histogram = new HashMap<T, Integer>();
for (T e : list) {
Integer val = histogram.get(e);
histogram.put(e, val == null ? 1 : val+1);
}
return histogram;
}
public static <T> List<T> generateInterectionList(List<T> list,Map<T,Integer> histogram ) {
List<T> res = new ArrayList<T>();
for (T e : list) {
Integer val = histogram.get(e);
if (val != null && val > 0) {
res.add(e);
histogram.put(e,val - 1);
}
}
return res;
}
public static <T> List<T> getIntersection(List<T> list1, List<T> list2) {
Map<T,Integer> histogram = populateHistogram(list1.size() > list2.size() ? list2 : list1);
return generateInterectionList(list1.size() > list2.size() ? list2 : list1,histogram);
}
public static void main(String[]args){
List<Integer> list1 = Arrays.asList(new Integer[]{1,2,5,4,1,3});
List<Integer> list2 = Arrays.asList(new Integer[]{1,2,1});
System.out.println(getIntersection(list1, list2));
}
注意它也可以在O(nlogn)
时间和O(logn)
空间(对于排序算法的堆栈跟踪)中进行排序,然后与每个列表的一个指针并行迭代
伪代码:
重复i1&lt; list1.length和i2&lt; list2.length:
答案 2 :(得分:0)
有没有理由不使用收藏品? retainAll(...)
方法可以满足您的需求:
List<Integer> list1 = ...
List<Integer> list2 = ...
List<Integer> intersection = list1.retainAll( list2 );
答案 3 :(得分:0)
一种方法是使用哈希表。从两个数组中创建两个单独的哈希表。键值对是(element,count)。现在浏览较小的哈希表并打印出count_min = min的每个元素count_min次数(表a中元素的计数,表b中元素的计数)。这是一种具有额外空间复杂度的线性算法。
空间复杂度= O(n + m)其中n和m是两个数组的大小。 时间复杂O(n)其中n> m。
答案 4 :(得分:0)
如果您对Java-8满意,那么我能想到的最简单的解决方案是使用流和过滤器。一个实现如下:
public static int[] intersection(int[] a, int[] b) {
return Arrays.stream(a)
.distinct()
.filter(x -> Arrays.stream(b).anyMatch(y -> y == x))
.toArray();
}