题目链接可见https://leetcode.com/problems/array-nesting/description/
A zero-indexed array A of length N contains all integers from 0 to N-1. Find and return the longest length of set S, where S[i] = {A[i], A[A[i]], A[A[A[i]]], … } subjected to the rule below.
Suppose the first element in S starts with the selection of element A[i] of index = i, the next element in S should be A[A[i]], and then A[A[A[i]]]… By that analogy, we stop adding right before a duplicate element occurs in S.
Example 1:
Input: A = [5,4,0,3,1,6,2]
Output: 4
Explanation:
A[0] = 5, A[1] = 4, A[2] = 0, A[3] = 3, A[4] = 1, A[5] = 6, A[6] = 2.
One of the longest S[K]:
S[0] = {A[0], A[5], A[6], A[2]} = {5, 6, 2, 0}
Note:
N is an integer within the range [1, 20,000].
The elements of A are all distinct.
Each element of A is an integer within the range [0, N-1].
这里题目要求的是:返回一个最大集合的长度。其中这个集合需要满足的条件如题目所示。
仔细分析这个集合的特点,若一个数字在这样的一个集合中,这个集合内的元素必然连成一个环。
如题目的示例,可构成这样的一个环
{% asset_img 2018-05-04-06-30-41.png this is an image %}
可知数组中的所有元素最后必定能够划分为独立的M个环,现在的问题就是求最大的环的长度了。
毫无疑问,我需要遍历每一个元素。
现在的问题是,对一个元素,我如何知道它所在的环被算过?知道被算过我又如何找到对应的环的长度?
这就需要我先清楚使用什么数据结构来存储我的计算结果。
当一个元素我没有计算过的时候,我通过一个集合存放当前环的元素,循环将下一个元素放入集合中,直到下一个元素已经在集合中。此时我们便计算得出了一个环的长度,并且这个环里的所有元素我以集合的方式存储进来。
我使用一个额外的数组存放每一个数组对应的环的长度,在计算一个环的长度后,我可以将环内的所有元素在数组中对应的位置的值置为环的长度,此后我便可以通过直接访问该数组的方式来得到环的长度,若为0,表示没计算过,那就去算。
class Solution:
def arrayNesting(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
self.nums = nums
self.lens = [0 for _ in range(len(nums))]
max_len = 0
for i in range(len(nums)):
cur_len = self.get_len(self.nums[i])
if max_len < cur_len:
max_len = cur_len
return max_len
def get_len(self, num):
if self.lens[num]:
return self.lens[num]
loop = set()
loop.add(num)
cur_num = num
while (self.nums[cur_num] not in loop):
loop.add(self.nums[cur_num])
cur_num = self.nums[cur_num]
for i in loop:
self.lens[i] = len(loop)
# print(loop)
return len(loop)
{% asset_img 2018-05-04-06-53-16.png this is an image %}
这个方法似乎还不够快,其实想了一下,没有必要用集合。
这里放一个大神的代码参考,简洁,优雅。
class Solution(object):
def arrayNesting(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
ans, step, n = 0, 0, len(nums)
seen = [False] * n
for i in range(n):
while not seen[i]:
seen[i] = True
i, step = nums[i], step + 1
ans = max(ans, step)
step = 0
return ans
这个代码beat了84.44%的python3 solutions。