Fork me on GitHub

版权声明 本站原创文章 由 萌叔 发表
转载请注明 萌叔 | https://vearne.cc

leecode 上第851题

1. 题目如下

在一组 N 个人(编号为 0, 1, 2, …, N-1)中,每个人都有不同数目的钱,以及不同程度的安静(quietness)。

为了方便起见,我们将编号为 x 的人简称为 “person x “。

如果能够肯定 person x 比 person y 更有钱的话,我们会说 richer[i] = [x, y] 。注意 richer 可能只是有效观察的一个子集。

另外,如果 person x 的安静程度为 q ,我们会说 quiet[x] = q 。

现在,返回答案 answer ,其中 answer[x] = y 的前提是,在所有拥有的钱不少于 person x 的人中,person y 是最安静的人(也就是安静值 quiet[y] 最小的人)。

示例:
输入:richer = [[1,0],[2,1],[3,1],[3,7],[4,3],[5,3],[6,3]], quiet = [3,2,5,4,6,1,7,0]
输出:[5,5,2,5,4,5,6,7]
解释: 
answer[0] = 5,
person 5 比 person 3 有更多的钱,person 3 比 person 1 有更多的钱,person 1 比 person 0 有更多的钱。
唯一较为安静(有较低的安静值 quiet[x])的人是 person 7,
但是目前还不清楚他是否比 person 0 更有钱。

answer[7] = 7,
在所有拥有的钱肯定不少于 person 7 的人中(这可能包括 person 3,4,5,6 以及 7),
最安静(有较低安静值 quiet[x])的人是 person 7。

其他的答案也可以用类似的推理来解释。

2. 提示

2.1 思考

对于示例,我们能够根据richer信息得出如下关系

我们能够得到富有程度的关系如上图

对于person_1,比他富有的人有person_2、person_3、person_4、person_5、person_6
我们可以从中找出最安静的人person_5

2.2 利用优化技巧

我们再重复这个过程的时候会发现,对于person_1

  • 比person_2的富有的人肯定比person_1富有
  • 比person_3的富有的人肯定比person_1富有

所以这个问题转变为一个递归问题
f(person_1) = pick(f(person_2), f(person_3), person_1)
从f(person_2)、f(person_3)、person_1中挑选最优解即可

2.3 最终代码

# -*- coding: utf-8 -*-
class Solution(object):
    def loudAndRich(self, richer, quiet):
        """
        :type richer: List[List[int]]
        :type quiet: List[int]
        :rtype: List[int]
        """
        N = len(quiet)
        internal = []
        for i in xrange(len(quiet)):
            internal.append([])

        for i in xrange(len(richer)):
            internal[richer[i][1]].append(richer[i][0])

        print "internal", internal
        # cache对person i 而言它的最优值
        cache = {}
        res = []
        # 只要做递归查找,就可以找到需要的结果
        for i in xrange(N):
            target = i
            target_value = quiet[i]

            q = [i]
            print "-" * 10
            print "target", target
            print "target_value", target_value
            print "q", q
            while len(q) > 0:
                item = q.pop()
                if item in cache:
                    if quiet[cache[item]] < target_value:
                        target_value = quiet[cache[item]]
                        target = cache[item]
                else:
                    if quiet[item] < target_value:
                        target_value = quiet[item]
                        target = item
                    q.extend(internal[item])
                    # print "q", q

            res.append(target)
            cache[i] = target
            # print res

        return res

请我喝瓶饮料

微信支付码

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据