查找具有最低第二次出现索引

时间:2017-08-14 03:28:23

标签: java algorithm data-structures

我正在尝试解决名为firstDuplicate的CodeFights上的问题 -

  

给定一个数组a,它只包含1到1之间的数字   a.length,找到第二个的第一个重复数字   发生具有最小指数。换句话说,如果还有更多   超过1个重复的数字,返回第二个数字   出现的索引小于另一个出现的索引   号码呢。如果没有这样的元素,则返回-1。

     

实施例

     

对于a = [2,3,3,1,5,2],输出应为firstDuplicate(a)=   3。

     

有两个重复:数字2和3.第二次出现3   索引比第二次出现的索引小2,所以   答案是3。

     

对于a = [2,4,3,5,1],输出应为firstDuplicate(a)= -1。

我的解决方案 -

public class FirstDuplicate {
    private static HashMap<Integer, Integer> counts = new HashMap<>();

    private static void findSecondIndexFrom(int[] num, int n, int i) {
    // given an array, a starting index and a number, find second occurrence of that number beginning from next index
        for(int x = i; x < num.length; x++) {
            if(num[x] == n) {
              // second occurrence found - place in map and terminate
                counts.put(n, x);
                return;
            }
        }


    }

    private static int firstDuplicate(int[] a) {
        // for each element in loop, if it's not already in hashmap
        // find it's second occurrence in array and place number and index in map

        for(int i = 0; i < a.length; i++) {
            if(!counts.containsKey(a[i])) {
                findSecondIndexFrom(a, a[i], i+1);
            }
        }

        System.out.println(counts);
        // if map is empty - no duplicate elements, return -1
        if(counts.size() == 0) {
            return -1;
        }
        // else - get array of values from map, sort it, find lowest value and return corresponding key

        ArrayList<Integer> values = new ArrayList<>(counts.values());
        Collections.sort(values);
        int lowest = values.get(0);
        //System.out.println(lowest);
        for(Map.Entry<Integer, Integer> entries: counts.entrySet()) {
            if(entries.getValue() == lowest) {
                return entries.getKey();
            }
        }
     return -1;
    }

    public static void main(String[] args) {
         // int[] a = new int[]{2, 3, 3, 1, 5, 2};
         //int[] a = new int[]{2, 4, 3, 5, 1};
         //int[] a = new int[]{8, 4, 6, 2, 6, 4, 7, 9, 5, 8};
        //int[] a = new int[]{1, 1, 2, 2, 1};

        int[] a = new int[]{10, 6, 8, 4, 9, 1, 7, 2, 5, 3};
        System.out.println(firstDuplicate(a));
    }


}

此解决方案仅针对CodeFights上的11个测试用例中的大约4个通过。但是,我在IDE中手动执行了每个测试用例,每个测试用例都产生了正确的结果。

我无法弄清楚为什么这在CodeFights中不起作用。它是否与使用静态HashMap

有关

2 个答案:

答案 0 :(得分:2)

编辑:由于添加和检查Set中是否存在元素可以一步完成,代码可以简化为:

public static int findDuplicateWithLowestIndex(int... a){
Set<Integer> set = new HashSet<>();
   for(int num : a){
     if(!set.add(num)){
        return num;
       }
    }
return -1; 
}

你完全正确的帕特里克。

答案 1 :(得分:0)

使用此解决方案:此处duplicateIndex应该是非常大的数字。

    package sample;

    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;

    public class Duplicate {

public static Integer secondIndex(Integer[] arr) {
    List<Integer> arrlist = new ArrayList<>(Arrays.asList(arr));
    int duplicateIndex = 999;
    int ele = 0;

    for (int i = 0; i < arrlist.size(); i++) {
        int secondIndex = getSecondIndex(arrlist, arrlist.get(i));

        if (secondIndex >= 0 && duplicateIndex > secondIndex) {
            duplicateIndex = secondIndex;
            ele = arrlist.get(i);
        }
    }

    return duplicateIndex == 999 ? -1 : ele;
}

public static int getSecondIndex(List<Integer> arr, int ele) {
    List<Integer> var0 = new ArrayList<>(arr);
    var0.set(var0.indexOf(ele), -1);
    return var0.indexOf(ele);
}

public static void main(String[] str) {
    // Integer[] arr = new Integer[] { 2, 3, 3, 1, 5, 2 };
    // Integer[] arr = new Integer[] { 2, 4, 3, 5, 1 };
    // Integer[] arr = new Integer[] { 8, 4, 6, 2, 6, 4, 7, 9, 5, 8 };
    // Integer[] arr = new Integer[]{1, 1, 2, 2, 1};
    Integer[] arr = new Integer[] { 10, 6, 8, 4, 9, 1, 7, 2, 5, 3 };
    System.out.println(secondIndex(arr));
}
}