按两个条件排序

时间:2019-01-25 18:36:41

标签: java algorithm sorting search

我有一个 n 个对象数组,其中包含字段:ID,价格。相同的ID在数组中可能会出现多次。我想为每个ID找到最便宜的 k 个对象,且最多不超过 m 个对象。

同时,k <= n,m <= k。

赞:

    onload = function() {
    if ('speechSynthesis' in window) with(speechSynthesis) {

        var playEle = document.querySelector('#play');
        var pauseEle = document.querySelector('#pause');
        var stopEle = document.querySelector('#stop');
        var flag = false;

        playEle.addEventListener('click', onClickPlay);
        pauseEle.addEventListener('click', onClickPause);
        stopEle.addEventListener('click', onClickStop);

        function onClickPlay() {
            if (!flag) {
                flag = true;
                utterance = new SpeechSynthesisUtterance(document.querySelector('article').textContent);
                utterance.voice = getVoices()[0];
                utterance.onend = function() {
                    flag = false;
                    playEle.className = pauseEle.className = '';
                    stopEle.className = 'stopped';
                };
                playEle.className = 'played';
                stopEle.className = '';
                speak(utterance);
            }
            if (paused) { /* unpause/resume narration */
                playEle.className = 'played';
                pauseEle.className = '';
                resume();
            }
        }

        function onClickPause() {
            if (speaking && !paused) { /* pause narration */
                pauseEle.className = 'paused';
                playEle.className = '';
                pause();
            }
        }

        function onClickStop() {
            if (speaking) { /* stop narration */
                /* for safari */
                stopEle.className = 'stopped';
                playEle.className = pauseEle.className = '';
                flag = false;
                cancel();

            }
        }

    }

    else { /* speech synthesis not supported */
        msg = document.createElement('h5');
        msg.textContent = "Detected no support for Speech Synthesis";
        msg.style.textAlign = 'center';
        msg.style.backgroundColor = 'red';
        msg.style.color = 'white';
        msg.style.marginTop = msg.style.marginBottom = 0;
        document.body.insertBefore(msg, document.querySelector('div'));
    }

}
n = 1,000,000
k = 10,000
m = 50

如果:

class Issue {
    int ID;
    int price;

    public Issue(int ID, int price) {
        this.ID = ID;
        this.price = price;
    }
}
Issue[] arr = {
    new Issue(1, 100),
    new Issue(1, 150),
    new Issue(1, 200),

    new Issue(2, 1),
    new Issue(2, 2),
    new Issue(2, 3),

    new Issue(3, 4),
    new Issue(3, 5),
    new Issue(3, 30),
    new Issue(3, 6),

    new Issue(4, 7),
    new Issue(4, 8),
    new Issue(4, 9),
    new Issue(4, 10),
};

类似的决定

n = 14
k = 5
m = 2

我使用java流解决了这个问题,但是使用几种方法,O表现不好。您会提出什么算法来解决?

@Xiangpeng感谢您的回答。你是真的吗?

new Issue(2, 1),
new Issue(2, 2),
new Issue(3, 4),
new Issue(3, 5),
new Issue(4, 7),

3 个答案:

答案 0 :(得分:1)

您需要一个具有两个条件的比较器。

Comparator.comparing((问题a)-> a.ID)

thenComparing 添加第二个条件,在这种情况下,请比较价格

list.sort(Comparator.comparing((Issue a)-> a.ID ).thenComparing((a,b)-> Integer.compare(a.price, b.price) ));

我建议使用getters和setters方法

list.sort(Comparator.comparing((Issue a)-> a.getId() ).thenComparing((a,b)-> Integer.compare(a.getPrice(), b.getPrice()) ));

答案 1 :(得分:0)

最简单的方法是按价格对问题进行排序,然后遍历它们,跟踪已使用给定ID选择的问题数(以便您可以跳过超出限制的任何问题)。选择正确数量的问题后,请中止。

所以:

Collections.sort(arr, (issueA, issueB) => Integer.compare(issueA.price, issueB.price));

final List<Issue> result = new ArrayList<>();
final Map<Integer, Integer> countsByID = new HashMap<>();

for (final Issue issue : arr) {
    if (! countsByID.containsKey(issue.ID)) {
        countsByID.put(issue.ID, 0);
    }

    if (countsByID.get(issue.ID) >= m) {
        continue;
    }

    result.add(issue);

    countsByID.put(issue.ID, countsByID.get(issue.ID) + 1);

    if (result.size() == k) {
        return result;
    }
}

return result; // couldn't find k values satisfying the restrictions

答案 2 :(得分:0)

您可以使用优先级队列结构。 https://docs.oracle.com/javase/10/docs/api/java/util/PriorityQueue.html

对于每个ID,请制作一个地图ID-> [大小为 m 的优先级队列],大小m表示在您已经添加 m 价格。

每个ID最多有 m 个价格,拍下这张地图并建立另一个[大小为 k 的优先级队列],即可解决问题。

复杂度为O(n * log(k))