两个有序数组间相加和的Topk问题

链接

给定两个有序数组arr1和arr2,再给定一个整数k,返回来自arr1和arr2的两个数相加和最大的前k个,两个数必须分别来自两个数组

import java.util.*;

public class Main {

    private static final int[] DX = {0, -1};

    private static final int[] DY = {-1, 0};

    private static String genKey(int x, int y) {
        return x + "_" + y;
    }


    private static int[] solve(int[] a, int[] b, int k) {
        if (a == null || a.length == 0 || b == null || b.length == 0) {
            return new int[0];
        }

        int n = a.length;
        int[] ret = new int[k];

        Set<String> visited = new HashSet<>();


        PriorityQueue<Node> queue = new PriorityQueue<>(new Comparator<Node>() {
            @Override
            public int compare(Node o1, Node o2) {
                return Integer.compare(o2.value, o1.value);
            }
        });

        queue.offer(new Node(a[n - 1] + b[n - 1], n - 1, n - 1));
        visited.add(genKey(n - 1, n - 1));


        while (!queue.isEmpty() && k > 0) {
            Node poll = queue.poll();
            ret[--k] = poll.value;

            for (int i = 0; i < 2; ++i) {
                int x = poll.x + DX[i];
                int y = poll.y + DY[i];
                if (x >= 0 && y >= 0 && !visited.contains(genKey(x, y))) {
                    queue.offer(new Node(a[x] + b[y], x, y));
                    visited.add(genKey(x, y));
                }
            }
        }


        return ret;
    }

    private static void print(int[] ret) {
        if (ret == null || ret.length == 0) {
            System.out.println();
            return;
        }
        System.out.print(ret[ret.length - 1]);
        for (int i = ret.length - 2; i >= 0; --i) {
            System.out.print(" " + ret[i]);
        }
        System.out.println();
    }

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {
            int n = in.nextInt();
            int k = in.nextInt();

            int[] a = new int[n];
            for (int i = 0; i < n; ++i) {
                a[i] = in.nextInt();
            }

            int[] b = new int[n];
            for (int i = 0; i < n; ++i) {
                b[i] = in.nextInt();
            }

            int[] ret = solve(a, b, k);
            print(ret);
        }
    }
}

class Node {
    int value;
    int x;
    int y;

    public Node(int value, int x, int y) {
        this.value = value;
        this.x = x;
        this.y = y;
    }
}
上一篇:linux安装ruby ruby-devel rubygems bundler


下一篇:单核内存解决topk问题