关于LeetCode的最大频率堆栈问题

时间:2018-12-22 01:05:40

标签: java

我正在尝试使用树集和hashMap的组合来解决leetcode上的最大频率堆栈问题。我的问题是,即使使用自定义类的类似接口,treeset的contains函数似乎也无法正常工作。它会添加多个具有相同值的项目。

我要去哪里错了?

代码如下:

class FreqStack {
    private int size = 0;
    HashMap<Integer, Element> map;
    TreeSet<Element> set;

    public FreqStack() {
        map = new HashMap<Integer, Element>();
        set = new TreeSet<Element>();
    }

    public void push(int x) {
        size++;
        Element elem = map.get(x);
        if (elem == null) {
            // System.out.println("creating new: " + x);
            elem = new Element(x);
        }
        elem.add(size);
        map.put(x, elem);
        if (set.contains(elem)) {
            System.out.println("set contains: " + elem.val);
            set.remove(elem);
        }
        set.add(elem);

        System.out.println(set.stream().map(v -> v.val).collect(Collectors.toList()));
    }

    public int pop() {
        // size--;
        Element elem = set.pollFirst();
        System.out.println(elem.val);
        elem.remove();

        if (elem.getFreq() > 0) {
            set.add(elem);
        } else {
            map.remove(elem.val);
        }

        System.out.println(set.stream().map(v -> v.val).collect(Collectors.toList()));
        return elem.val;
    }

    class Element implements Comparable<Element> {
        int val;
        LinkedList<Integer> rank;

        Element(int val) {
            this.val = val;
            this.rank = new LinkedList<Integer>();
        }

        void add(int count) {
            System.out.println("Adding " + val + " - count: " + count);
            rank.add(count);
        }

        void remove() {
            System.out.println("Removing: " + rank.size());
            rank.pollLast();
        }

        int getRank() {
            return rank.peekLast();
        }

        int getFreq() {
            return rank.size();
        }

        @Override
        public int compareTo(Element e) {
            System.out.println("Comparing: " + val + " and " + e.val);
            if (val == e.val)
                return 0;

            if (getFreq() == e.getFreq()) {
                return e.getRank() - getRank();
            }

            return e.getFreq() - getFreq();
        }
        @Override
        public int hashCode() {
            return val;    
        }

        @Override
        public boolean equals(Object o) {
           return (o instanceof Element) && (this.compareTo((Element) o) == 0);
        }
    }
}

/**
 * Your FreqStack object will be instantiated and called as such:
 * FreqStack obj = new FreqStack();
 * obj.push(x);
 * int param_2 = obj.pop();
 */

这是零件输出。请注意它是如何两次加5:

Adding 5 - count: 1
Comparing: 5 and 5
[5]
Adding 1 - count: 2
Comparing: 1 and 5
Comparing: 1 and 5
[1, 5]
Adding 2 - count: 3
Comparing: 2 and 5
Comparing: 2 and 1
Comparing: 2 and 5
Comparing: 2 and 1
[2, 1, 5]
Adding 5 - count: 4
Comparing: 5 and 1
Comparing: 5 and 2
Comparing: 5 and 1
Comparing: 5 and 2
[5, 2, 1, 5]

1 个答案:

答案 0 :(得分:0)

compareTo方法应该只比较元素的val,不是吗?解决此问题的两种方法是:

  • 使用HashSet代替TreeSet。
  • 按如下所示更改您的compareTO:

    public int compareTo(Element e) {
        System.out.println("Comparing: " + val + " and " + e.val);
        return Integer.compare(val, e.val);
    }
    

如果这些不能满足您的要求,请您再解释一下当您覆盖compareTo方法时要达到的目标。看来您应该只考虑元素的值,但同时也使用了Freq和Rank。