OA原题描述参考:

注意:具体抽到的题目可能会有细微变化。

假设有个Movie类,

public class Movie

{

int movieId;.

float rating;

List<Movie> similarMovies

}

现在要求找到 k个和movie最相似 的movies。

函数的signature大概是这样的:

public static List <Movie> getNearest(Movie movie, int numSimilar)。

举个栗子:

m0 <--> m1, similarity 2-google 1point3acres

mo <--> m2, similarity 3

m1 <--> m3, similarity 4

m2 <--> m5, similaity 5

如果要返回和mo最相似的movie, 那么应该返回 m5 (只有有一条路径从 m1到 m5, 并且 5是最大的); 如果返回3个最相似的就返回 m2, m3, m5(顺序不重要); 如果需要返回10个,但是相似的只有9个,那么就返回9个。

source movie本身不能在返回结果里面。

可以的一个做法是 dfs + min-Heap(PriorityQueue), 我们一直做dfs, 每次碰到一个新的movie,如果现在queue的size比 k小的话,直接加到queue里面; 如果新movie的rating比queue top movie的rating高的话, 把顶部movie

踢出队列,加上这个新的。

update: 应该返回 m5 (只有有一条路径从 m1到 m5, 并且 5是最大的) 应该返回 m5 (只要有一条路径从 m1到 m5, 并且 5是最大的)

解题思路参考:

BFS找,dfs的我没有实现。

参考答案:

package com.amazon;

import java.util.*;

/**
 * Created by Tian on 2017/4/8.
 */
public class SolutionMovieNetwork {

    Comparator<Movie> queueComp = new Comparator<Movie>() {
        public int compare(Movie a, Movie b) {
            return (a.rating - b.rating > 0 ? 1 : -1);
        }
    };

    public List<Movie> getNearest(Movie movie, int k) {
        /*
            A priorityQueue to keep minHeap of top k rating
            Use DFS level order traverse all nodes
         */
        PriorityQueue<Movie> pq = new PriorityQueue<Movie>(k, queueComp);
        Queue<Movie> queue = new LinkedList<Movie>();
        HashSet<Movie> hash = new HashSet<Movie>();

        for (Movie indegree : movie.similarMovies) {
            if (!hash.contains(indegree)) {
                queue.offer(indegree);
                hash.add(indegree);
            }
        }

//        queue.offer(movie);
//        hash.add(movie);
        while (!queue.isEmpty()) {
            Movie oneMovie = queue.poll();
            if (pq.size() < k) {
                pq.add(oneMovie);
            } else {
                if (pq.peek().rating < oneMovie.rating) {
                    pq.poll();
                    pq.offer(oneMovie);
                }
            }
            for (Movie similar : oneMovie.similarMovies) {
                if (!hash.contains(similar)) {
                    pq.offer(similar);
                    hash.add(similar);
                }
            }
        }

        List<Movie> res = new ArrayList<Movie>();
        while (!pq.isEmpty()) {
            res.add(pq.poll());
        }

        return res;
    }

    public static class Movie
    {
        int movieId;
        float rating;
        List<Movie> similarMovies;
    }
}

results matching ""

    No results matching ""