class Solution:
def arrayNesting(self, nums):
visited = [False] * len(nums)
max_len = 0
for i in range(len(nums)):
if not visited[i]:
start = nums[i]
count = 0
while not visited[start]:
visited[start] = True
start = nums[start]
count += 1
max_len = max(max_len, count)
return max_len
class Solution {
public:
int arrayNesting(vector<int>& nums) {
int n = nums.size();
vector<bool> visited(n, false);
int maxLen = 0;
for (int i = 0; i < n; ++i) {
if (!visited[i]) {
int start = nums[i], count = 0;
while (!visited[start]) {
visited[start] = true;
start = nums[start];
++count;
}
maxLen = max(maxLen, count);
}
}
return maxLen;
}
};
class Solution {
public int arrayNesting(int[] nums) {
int n = nums.length;
boolean[] visited = new boolean[n];
int maxLen = 0;
for (int i = 0; i < n; i++) {
if (!visited[i]) {
int start = nums[i], count = 0;
while (!visited[start]) {
visited[start] = true;
start = nums[start];
count++;
}
maxLen = Math.max(maxLen, count);
}
}
return maxLen;
}
}
var arrayNesting = function(nums) {
let visited = new Array(nums.length).fill(false);
let maxLen = 0;
for (let i = 0; i < nums.length; i++) {
if (!visited[i]) {
let start = nums[i], count = 0;
while (!visited[start]) {
visited[start] = true;
start = nums[start];
count++;
}
maxLen = Math.max(maxLen, count);
}
}
return maxLen;
};
Given an array nums
of length n
containing all the integers from 0
to n-1
in some order (a permutation), you are to find the length of the largest set S
that can be constructed as follows:
i
in nums
.S = {nums[i]}
.j = nums[i]
and add nums[j]
to S
.j = nums[j]
and add nums[j]
to S
.S
(i.e., the sequence forms a cycle).
The goal is to return the size of the largest possible set S
you can generate from any starting index. The key constraints are:
nums
is unique and in the range 0
to n-1
.S
; once an element is in S
, you must stop if you encounter it again.
At first glance, the problem asks us to explore cycles in a permutation. We could try to build the set S
from every possible starting index, following the chain until we hit a repeated element. This would mean, for each index, we follow the chain of nums
until we loop back, counting the size of the set.
However, if we naively do this for every index, we might repeat work, since cycles overlap and every element belongs to exactly one cycle. To optimize, we can use a visited array to track which elements we've already included in some set S
. Once an element is visited, we know its cycle has already been counted, so we can skip it in future iterations.
This transition from brute-force (re-exploring cycles) to optimization (marking visited) is the key insight that turns a potentially slow solution into an efficient one.
visited
array of the same length as nums
, initialized to False
(or false
).maxLen
to track the largest set size found.i
from 0
to n-1
:visited[i]
is True
, skip to the next index (we've already processed its cycle).visited[i]
is False
, start a new set S
from this index.start = nums[i]
and initialize a count
variable to zero.visited[start]
is False
:
visited[start]
as True
.start = nums[start]
.count
by 1.maxLen
if count
is larger than the previous maximum.maxLen
as the result.This approach ensures each element is only visited once, making the solution efficient.
Let's use the sample input nums = [5,4,0,3,1,6,2]
.
nums[0] = 5
→ nums[5] = 6
→ nums[6] = 2
→ nums[2] = 0
nums[1] = 4
→ nums[4] = 1
nums[3] = 3
The largest set found is of length 4.
O(n^2)
in the worst case.O(n)
.O(n)
for the visited
array.Thus, the optimized approach is linear time and space.
The Array Nesting problem is about finding the longest cycle in a permutation array by following chains of indices. By marking elements as visited, we avoid redundant work and ensure each cycle is only counted once. The result is an elegant and efficient O(n)
solution that leverages the properties of permutations and cycle detection.