[英]How to find the smallest number that is common among the 3 arrays?
這是問題:
Given 3 random arrays of integers, write a method to find the smallest number that is common among the 3 arrays. HINT: Sort first and just traverse first few elements until you reach the common number
[-1,-2, 4,5,6,1,2,3,3,3,1,1,1]
[54,6,7,8,1,3,5,1]
[1,6,9,1,0,2,1]
result = 1
我編寫了一個有效的解決方案代碼,但我想知道是否有更簡單,更有效的方法來執行此操作。
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
public class Smcomm {
public static void main(String[] args) {
int[] A = {-1,-2,4,5,6,1,2,3,3,3,1,1,1};
int[] B = {54,6,7,8,1,3,5,1};
int[] C = {1,6,9,1,0,2,1};
ArrayList<Integer> ar1 = new ArrayList<Integer>();
ArrayList<Integer> ar2 = new ArrayList<Integer>();
ArrayList<Integer> ar3 = new ArrayList<Integer>();
for(int el: A){
ar1.add(el);
}
for(int el: B){
ar2.add(el);
}
for(int el: C){
ar3.add(el);
}
Collections.sort(ar1);
Collections.sort(ar2);
Collections.sort(ar3);
printer(ar1);
printer(ar2);
printer(ar3);
finder(ar1,ar2,ar3);
}
static void printer(ArrayList ar){
Iterator<Integer> it = ar.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
System.out.println("--------------------");
}
static void finder(ArrayList ar1, ArrayList ar2, ArrayList ar3){
ar1.retainAll(ar2);
ar1.retainAll(ar3);
if(ar1.size()>0){
System.out.println(ar1.get(1));
}else {
System.out.println("no comm el");
}
}
}
不convice我完全就是因為的retainAll我認為該方法具有復雜度為O(n ^ 2)。
我不需要找到所有元素,但是我只想找到最小的元素。 您是否知道在數組中找到第一個公共元素時是否有可能停止該方法的執行? 應該不難,因為數組已經排序。
謝謝您的幫助。
稍微不同的方法:
兩者都包含的第一個數字必須是最小的公共條目。 這樣可以防止您查看重復的條目(在這里真的沒關系),並且還避免了對所有三個數組進行排序。
最后,對於如此小的示例,任何正確的解決方案都足夠了。 僅當您在談論包含成千上萬甚至數百萬個條目的列表時,不同解決方案的潛在權衡才有意義。
您可以僅使用Arrays和foreach循環以簡單的方式實現此目的:
這是如何實現此目的的示例:
public static void main(String[] args) {
int[] A = {-1, -2, 4, 5, 6, 1, 2, 3, 3, 3, 1, 1, 1};
int[] B = {54, 6, 7, 8, 1, 3, 5, 1};
int[] C = {1, 6, 9, 1, 0, 2, 1};
Arrays.sort(A);
Arrays.sort(B);
Arrays.sort(C);
Optional<Integer> inCommon = findInCommon(A, B, C);
if (inCommon.isPresent()) {
System.out.println(inCommon.get());
} else {
System.out.println("no comm el");
}
}
private static Optional<Integer> findInCommon(int[] A, int[] B, int[] C) {
int lastB = 0;
int lastC = 0;
for (int valA : A) {
while (B[lastB] < valA) lastB++;
while (C[lastC] < valA) lastC++;
if (valA == B[lastB] && valA == C[lastC]) {
return Optional.of(valA);
}
}
return Optional.empty();
}
另一種使用Java 8流的方法,先計算交集,然后求出最小值:
List<Integer> list1 = Arrays.asList(A);
List<Integer> list2 = Arrays.asList(B);
List<Integer> list3 = Arrays.asList(C);
Set<Integer> commonElements = list1.stream().filter(list2::contains).filter(list3::contains).collect(Collectors.toSet());
int minimumCommonElement = Collections.min(commonElements);
我認為最簡單的方法是將元素存儲在TreeSet中(自然排序並刪除重復項),而不是ArrayList,然后遍歷集合1中的每個元素,直到找到存在於所有元素中的元素為止。 3套
static void finder(Set<Integer> s1, Set<Integer> s2, Set<Integer> s3) {
boolean found=false;
for (int i: s1) {
if (s2.contains(i) && s3.contains(i)) {
System.out.println(i);
found=true;
break;
}
}
if (!found) {
System.out.println("no comm el");
}
}
以下效果很好。 在我看來,您只需要對列表之一進行排序,並將其用作插入的來源。
List<Integer> list1 = new ArrayList<>(
List.of(-1, -2, 4, 5, 6, 3, 1, 2, 3, 3, 3, 1, 1, 1));
List<Integer> list2 = new ArrayList<>(List.of(54, 6, 7, 8, -4, 1, 3, 5, 1));
List<Integer> list3 = new ArrayList<>(List.of(1, 6, 9, 1, 0, -4, 2, 1));
Collections.sort(list1);
for (int e : list1) {
if (list2.contains(e) && list3.contains(e)) {
System.out.println(e);
break;
}
}
這里的想法是,如果e
在list1
(排序后的列表)中最小,那么如果它在list2
和list3
則它必須是所有三個中最小的。
通過使用集合刪除重復項可能會有所改善。 但是,除非最初將數據包含在要啟動的集合中,否則這樣做也可能會導致性能問題。
剛看過其他答案后,有人建議對最小的列表(或集合)進行排序。 這是我從未考慮過的好主意。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.