1

我正在尝试查找仅在ArrayList.

我实现了多少(最好具有最佳的时间复杂度)?

下面是我的方法:

  public static int countNonRepeats(WordStream words) {

    ArrayList<String> list = new ArrayList<String>();
    for (String i : words) {
      list.add(i);
    }

    Collections.sort(list);

    for (int i = 1; i < list.size(); i++) {
      if (list.get(i).equals(list.get(i - 1))) {
        list.remove(list.get(i));
        list.remove(list.get(i - 1));
      }
    }

    System.out.println(list);

    return list.size();
  }

为什么它不删除 and 处的list.get(i)字符串list.get(i-1)

4

4 回答 4

3

不需要排序。更好的方法是使用两个 HashSet 一个来维护重复单词,一个用于非重复单词。由于 HashSet 内部使用 HashMap,理想情况下 contains、get、put 操作的复杂度为 o(1)。所以这种方法的整体复杂度是 o(n)。

    public static int countNonRepeats(List<String> words) {

    Set<String> nonRepeating = new HashSet<String>();
    Set<String> repeating = new HashSet<String>();


    for (String i : words) {
        if(!repeating.contains(i)) {
            if(nonRepeating.contains(i)){
                repeating.add(i);
                nonRepeating.remove(i);
            }else {
                nonRepeating.add(i);
            }
        }
    }

    System.out.println(nonRepeating.size());

    return nonRepeating.size();
}
于 2016-03-14T19:48:48.347 回答
2

这里有一个简单的建议:

  1. 首先,按字母数字顺序对数组进行排序
  2. 循环遍历,if( !list.get(i).equals(list.get(i+1)) ) → unique
  3. 如果发现重复项,i请递增直到达到不同的字符串

这将具有排序算法的复杂性,因为步骤 2+3 应该是 O(n)

于 2016-03-14T19:18:52.477 回答
2

是否有任何特定的使用需求ArrayList?您可以使用HashSet.

这是代码片段:

public static void main (String[] args) {
    String[] words = {"foo","bar","foo","fo","of","bar","of","ba","of","ab"};
    Set<String> set = new HashSet<>();
    Set<String> common = new HashSet<>();
    for (String i : words) {
        if(!set.add(i)) {
            common.add(i);
        }
    }

    System.out.println(set.size() - common.size());
}

输出:

3

这是修改后的代码:

public static int countNonRepeats(WordStream words) {
    Set<String> set = new HashSet<>();
    Set<String> common = new HashSet<>();
    for (String i : words) {
        if(!set.add(i)) {
            common.add(i);
        }
    }

    return (set.size() - common.size());
}
于 2016-03-14T19:31:34.787 回答
0

您可以使用 hashmap 来实现这一点。通过这种方法,我们可以计算所有单词的出现次数,
如果我们只对唯一单词感兴趣,则访问 count = 1 的元素。
HashMap<String,Integer>- key 表示来自 arraylist 的字符串,Integer 表示计数的发生。

        ArrayList<String> list = new ArrayList<String>();
        HashMap<String, Integer> hashMap = new HashMap<String, Integer>();

        for (int i = 0; i < list.size(); i++) {

            String key = list.get(i);

            if (hashMap.get(key) != null) {
                int value = hashMap.get(key);
                value++;
                hashMap.put(key, value);
            } else {
                    hashMap.put(key, 1);
            }

        }
        int uniqueCount = 0;
        Iterator it = hashMap.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry pair = (Map.Entry) it.next();
            if ((int) pair.getValue() == 1)
                uniqueCount++;
        }
        System.out.println(uniqueCount);
于 2016-03-14T19:48:40.833 回答