查找列表中的频率差异元素

时间:2015-04-28 16:11:48

标签: java algorithm dictionary hashmap

其实我正在尝试解决这个问题hackerrank Missing Numbers

请允许我添加一些描述,实际上有两个数字列表,几乎相同,但事实上有些在第一个列表中缺失,所以第二个列表的所有数字都完整但第一个有一些他们失踪了,我们只需打印第一个列表中缺少的数字。

问题陈述

艺术家Numeros有两个A和B列表,因此B是A的排列.Numeros对这些列表感到非常自豪。不幸的是,在将它们从一个展览运送到另一个展览时,A的一些数字被遗漏了。你能找到丢失的号码吗?

注释

如果列表中出现多次号码,则必须确保两个列表中该号码的频率相同。如果不是这样,那么它也是一个缺失的数字。

您必须按升序打印所有缺失的数字。

打印每个丢失的号码一次,即使多次丢失也是如此。

B中最大和最小数字之间的差异小于或等于100.

输入格式 将有四行输入:

n - the size of the first list 
This is followed by n space-separated integers that make up the first list. 
m - the size of the second list 
This is followed by m space-separated integers that make up the second list.

输出格式 按升序输出缺失的数字: -

约束

1≤n,m≤1000010 
1≤x≤10000,x∈B 
Xmax−Xmin<101

示例输入

10
203 204 205 206 207 208 203 204 205 206
13
203 204 204 205 206 207 205 208 203 206 205 206 204

示例输出

204 205 206

我写了代码: -

这是: -

import java.io.*;
import java.util.*;

public class Solution {

    public static void main(String[] args) {
        /* Enter your code here. Read input from STDIN. Print output to STDOUT. Your class should be named Solution. */
        Scanner scan = new Scanner(System.in);
        int n = scan.nextInt();
        Map<Integer, Integer> mA = new HashMap<>(n);
        int curr = 0;
        while(n--> 0){// Creating the first map having number & its frequency
            curr = scan.nextInt();
            if(mA.containsKey(curr)){
                Integer prev = mA.get(curr);
                mA.put(curr, prev + 1);
            }else{
                mA.put(curr, 1);
            }
        }

        int n1 = scan.nextInt();
        Map<Integer, Integer> mB = new HashMap<>(n1);
        while(n1--> 0){// Creating the second map having number & its frequency
            curr = scan.nextInt();
            if(mB.containsKey(curr)){
                Integer prev = mB.get(curr);
                mB.put(curr, prev + 1);
            }else{
                mB.put(curr, 1);
            }   
        }

            List<Integer> l = new ArrayList<>();

            //Problem I think is this part somewhere I am not doing it correct in this loop
            for(Map.Entry<Integer, Integer> entry : mB.entrySet()){
                Integer k = entry.getKey();
                Integer v = entry.getValue();
                if(!mA.containsKey(k)){
                   l.add(k);
                }else if(mA.get(k) != v){
                    l.add(k);
                }
            }
            Collections.sort(l);
            List<Integer> list = new ArrayList<>(new LinkedHashSet<Integer>(l));

           for(Integer i : l){
               System.out.print(i + " ");
           }
        }
}

我认为问题出现在for循环中,我在比较两个地图中的条目。我想我的做法并不正确!!  因为它打印的数字在两张地图中具有相同的频率计数。

4 个答案:

答案 0 :(得分:2)

问题是

for(Map.Entry<Integer, Integer> entry : mB.entrySet()){
    Integer k = entry.getKey();
    Integer v = entry.getValue();
    if(!mA.containsKey(k)){
        l.add(k);
    }else if(mA.get(k).intValue() != v.intValue()){//This is the problem
        l.add(k);
    }
}

因为,之前您正在比较两个整数对象而不是两个int值(对于小整数值,它全部映射到同一个对象,但对于较大的一个,Java创建新对象做自动拳击时。)

这个问题,实际上只需要一个Map,如果你使用TreeMap而不是HashMap,你会发现这更方便。

请注意Xmax - Xmin < 101,因此我们甚至可以使用数组data[101]来存储数字,以便进一步改进。

答案 1 :(得分:1)

尝试使用数组:

int[] a = new int[n];
int[] b = new int[m];
// read into a and b
int[] freqs = new int[10001];

for (int i = 0; i < m; i++)
{
    freqs[b[i]]++;
}
for (int i = 0; i < n; i++)
{
    freqs[a[i]]--;
}
for (int i = 0; i <= 10000; i++)
{
    if (freqs[i] > 0) System.out.println(i + " ");
}

答案 2 :(得分:1)

  void printmissing(HashMap<Integer, Integer> firstset,HashMap<Integer, Integer> secondset){
    Set<Integer> keys=secondset.keySet();
    for(Integer k:keys){
        secondset.put(k, secondset.get(k)-firstset.get(k));
    }
    for(Integer k:keys){
        if(secondset.get(k)>0)
            System.out.print(" "+k);
    }

在main方法的LinkedHashMap中添加整数值,并调用上面的方法按顺序显示缺失的数字

    HashMap<Integer, Integer> firstset=new LinkedHashMap<>();
    HashMap<Integer, Integer>  secondset=new LinkedHashMap<>();

答案 3 :(得分:0)

试试这个

`

public class Abce{
    public static void main(String[] args) {
        ArrayList<Integer> A = new ArrayList<Integer>();
        A.add(1);
        A.add(1);
        A.add(1);
        A.add(2);
        A.add(1);

        ArrayList<Integer> B = new ArrayList<Integer>();

        B.add(1);
        B.add(1);
        B.add(2);
        B.add(1);

        //Find and remove
        for (Integer integer : B) {
            if (A.contains(integer)) {
                A.remove(integer);
            }

        }

        //Print the remaining items
        for (Integer integer : A) {
            System.out.println(integer);
        }

    }
}`