本文主要是介绍Leetcode 3017. Count the Number of Houses at a Certain Distance II,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
- Leetcode 3017. Count the Number of Houses at a Certain Distance II
- 1. 解题思路
- 2. 代码实现
- 题目链接:3017. Count the Number of Houses at a Certain Distance II
1. 解题思路
这一题其实思路上还是比较简单的,显然任何一个图都可以拆分为以下三个部分:
- 环
- 环的左侧
- 环的右侧
因此,我们总可以将所有的城市关系分为下述三种:
- 环内部的两个城市
- 环外部的两个城市
- 环外部的一个城市与环内的一个城市
因此,我们只需要分类讨论上述三种情况下的各个distance的种数然后相加即可。
首先,对于环内的两个城市,这个是比较简单的,对于任何一个距离,从任何一个城市出发,从左从右都可以到达一个城市,因此,任何一个距离 d ≤ ⌊ n 2 ⌋ d \leq \lfloor \frac{n}{2} \rfloor d≤⌊2n⌋的距离都对应 2 n 2n 2n的走法,唯一需要注意一下的就是 n n n为奇数的情况,此时对于 ⌊ n 2 ⌋ \lfloor \frac{n}{2} \rfloor ⌊2n⌋的距离下,左右走到的都是同一个城市,因此需要修正为 n n n。
然后,对于第二种情况,对于环外的两个城市,显然我们将环视为两个节点即可,此时就是一条单链,任意距离 d d d对应的走法总数就是 n − d n-d n−d。不过,我们需要注意一下,因为环上的两个点事实上是不允许走到的,因此我们需要额外刨除一下以这两个点作为起点以及终点时的情况。
最后,对于第三种情况,则稍微复杂一点,显然,我们只需要考虑一侧进入到环的情况即可,此时我们不难按照1中的情况获得从环的入口到达环上任意一点的走法种数,然后,我们对环入口线段上的所有点进行一下累加即可,对应情况极为:
a b c d e a b c d e a b c d e a b c d e ⋯ \begin{aligned} a && b && c && d && e \\ && a && b && c && d && e \\ && && a && b && c && d && e \\ && && && a && b && c && d && e \\ && && && && && && && &\cdots \end{aligned} abacbadcbaedcbedcede⋯
这个我们用一个累积数组进行计算即可。
当然,这里也有一个特殊情况,就是当环的起点和终点是同一个点时,此时走环反而要多走一步,因此我们直接需要过滤掉这种情况。
2. 代码实现
给出python代码实现如下:
class Solution:def countOfPairs(self, n: int, x: int, y: int) -> List[int]:x, y = (x, y) if x <= y else (y, x)if x == y:return [2*(n-1-i) for i in range(n)]inside = y-x+1left, right = x-1, n-ydef cal_outer(a, b):m = a+b+2ans = [2*(m-1-i) for i in range(m)]for i in range(a):ans[i] -= 2ans[i+1] -= 2for i in range(b):ans[i] -= 2ans[i+1] -= 2ans[0] -= 2return ans + [0] * (n-len(ans))def cal_inner(m):if m % 2 == 0:ans = [m*2 for i in range(1, m//2)] + [m]else:ans = [m*2 for i in range(1, (m+1)//2)]return ans + [0] * (n-len(ans))def cal_cross(a, b):ans= [0 for _ in range(n)]if a == 0:return anss = [1] + [2 for _ in range((b-1)//2)]if b % 2 == 0:s = s + [1]m = len(s)s = [0] + list(accumulate(s))for i in range(a+m-1):ans[i] = 2*(s[min(i+1, m)] - s[max(0, i-a+1)])return ansinner = cal_inner(inside)outer = cal_outer(left, right)left_cross = cal_cross(left, inside)right_cross = cal_cross(right, inside)ans = [inner[i]+outer[i]+left_cross[i]+right_cross[i] for i in range(n)]return ans
提交代码评测得到:耗时691ms,占用内存36.1MB。
这篇关于Leetcode 3017. Count the Number of Houses at a Certain Distance II的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!