题目
索引从0
开始长度为N
的数组A
,包含0
到N - 1
的所有整数。找到最大的集合S
并返回其大小,其中 S[i] = {A[i], A[A[i]], A[A[A[i]]], ... }
且遵守以下的规则。
假设选择索引为i
的元素A[i]
为S
的第一个元素,S
的下一个元素应该是A[A[i]]
,之后是A[A[A[i]]]...
以此类推,不断添加直到S
出现重复的元素。
示例 1:
输入: A = [5,4,0,3,1,6,2]
输出: 4
解释:
A[0] = 5, A[1] = 4, A[2] = 0, A[3] = 3, A[4] = 1, A[5] = 6, A[6] = 2.
其中一种最长的 S[K]:
S[0] = {A[0], A[5], A[6], A[2]} = {5, 6, 2, 0}
提示:
N
是[1, 20,000]
之间的整数。A
中不含有重复的元素。A
中的元素大小在[0, N-1]
之间。
题解1(TLE)
思路
- 暴力深搜所有情况,求取最大值
代码
class Solution:
def arrayNesting(self, nums: List[int]) -> int:
maxDepth = -1
def dfs(n: int, visited: set, depth: int):
nonlocal maxDepth
if n not in visited:
visited.add(n)
dfs(nums[n], visited, depth+1)
maxDepth = max(maxDepth, depth)
for n in nums:
dfs(n,set(),0)
return maxDepth
复杂度
- 时间复杂度: O ( n 2 ) O(n^2) O(n2)
- 空间复杂度: O ( n ) O(n) O(n)
题解2(TLE)
思路
- 相对于题解1,使用尾递归进行优化
代码
class Solution:
def arrayNesting(self, nums: List[int]) -> int:
maxDepth = -1
def dfs(n: int, visited: set):
if n not in visited:
visited.add(n)
return dfs(nums[n], visited) + 1
else: return 0
for n in nums:
maxDepth = max(maxDepth, dfs(n,set()))
return maxDepth
复杂度
- 时间复杂度: O ( n 2 ) O(n^2) O(n2)
- 空间复杂度: O ( n ) O(n) O(n)
题解3
思路
- 该题相当于将所有的数作为节点,形成的图寻找最大的环的长度
- 因为所有结点的出度为1,所以访问过的节点无需重新访问
代码
class Solution:
def arrayNesting(self, nums: List[int]) -> int:
res = 0
visited = [False] * len(nums)
for i in range(len(nums)):
count = 0
while not visited[i]:
visited[i] = True
i = nums[i]
count += 1
res = max(res, count)
return res
复杂度
- 时间复杂度: O ( n ) O(n) O(n)
- 空间复杂度: O ( n ) O(n) O(n)
题解4
思路
- 因为每个节点至多只访问一次,所以将是否访问过的信息保存在原数组当中 标记为-1
代码
class Solution:
def arrayNesting(self, nums: List[int]) -> int:
res = 0
for i in range(len(nums)):
count = 0
while nums[i] != -1:
tempN = nums[i]
nums[i] = -1
i = tempN
count += 1
res = max(res, count)
return res
复杂度
- 时间复杂度: O ( n ) O(n) O(n)
- 空间复杂度: O ( 1 ) O(1) O(1)