Skip to content

Commit e094e6b

Browse files
authored
Merge pull request #1299 from shreyash3087/add/leetcode-565
Docs: Added Solutions to Leetcode 565
2 parents 6030d04 + 2024e7a commit e094e6b

File tree

2 files changed

+270
-1
lines changed

2 files changed

+270
-1
lines changed

dsa-problems/leetcode-problems/0500-0599.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,7 @@ export const problems =[
386386
"problemName": "565. Array Nesting",
387387
"difficulty": "Medium",
388388
"leetCodeLink": "https://leetcode.com/problems/array-nesting",
389-
"solutionLink": "#"
389+
"solutionLink": "/dsa-solutions/lc-solutions/0500-0599/array-nesting"
390390
},
391391
{
392392
"problemName": "566. Reshape the Matrix",
Lines changed: 269 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,269 @@
1+
---
2+
id: array-nesting
3+
title: Array Nesting
4+
sidebar_label: 0565 - Array Nesting
5+
tags:
6+
- Depth-First Search
7+
- Array
8+
- Dynamic Programming
9+
description: "This is a solution to the Array Nesting problem on LeetCode."
10+
---
11+
12+
## Problem Description
13+
14+
You are given an integer array `nums` of length `n` where `nums` is a permutation of the numbers in the range `[0, n - 1]`.
15+
16+
You should build a set `s[k] = {nums[k], nums[nums[k]], nums[nums[nums[k]]], ... }` subjected to the following rule:
17+
18+
- The first element in `s[k]` starts with the selection of the element `nums[k]` of `index = k`.
19+
- The next element in `s[k]` should be `nums[nums[k]]`, and then `nums[nums[nums[k]]]`, and so on.
20+
- We stop adding right before a duplicate element occurs in `s[k]`.
21+
- Return the longest length of a set `s[k]`.
22+
23+
### Examples
24+
25+
**Example 1:**
26+
27+
```
28+
Input: nums = [5,4,0,3,1,6,2]
29+
Output: 4
30+
Explanation:
31+
nums[0] = 5, nums[1] = 4, nums[2] = 0, nums[3] = 3, nums[4] = 1, nums[5] = 6, nums[6] = 2.
32+
One of the longest sets s[k]:
33+
s[0] = {nums[0], nums[5], nums[6], nums[2]} = {5, 6, 2, 0}
34+
```
35+
36+
**Example 2:**
37+
38+
```
39+
Input: nums = [0,1,2]
40+
Output: 1
41+
```
42+
43+
### Constraints
44+
45+
- $1 <= nums.length <= 10^5$
46+
- $0 <= nums[i] < nums.length$
47+
- All the values of `nums` are **unique**.
48+
49+
## Solution for Array Nesting
50+
51+
### Approach #1 Brute Force [Time Limit Exceeded]
52+
53+
The simplest method is to iterate over all the indices of the given nums array. For every index i chosen, we find the element nums[i] and increment the count for a new element added for the current index i. Since nums[i] has to act as the new index for finding the next element belonging to the set corresponding to the index i, the new index is j=nums[i].
54+
55+
We continue this process of index updation and keep on incrementing the count for new elements added to the set corresponding to the index i. Now, since all the elements in nums lie in the range (0,...,N−1), the new indices generated will never lie outside the array size limits. But, we'll always reach a point where the current element becomes equal to the element nums[i] with which we started the nestings in the first place. Thus, after this, the new indices generated will be just the repetitions of the previously generated ones, and thus would not lead to an increase in the size of the current set. Thus, this condition of the current number being equal to the starting number acts as the terminating condition for count incrementation for a particular index.
56+
57+
We do the same process for every index chosen as the starting index. At the end, the maximum value of count obtained gives the size of the largest set.
58+
59+
## Code in Different Languages
60+
61+
<Tabs>
62+
<TabItem value="cpp" label="C++">
63+
<SolutionAuthor name="@Shreyash3087"/>
64+
65+
```cpp
66+
#include <vector>
67+
#include <algorithm> // For std::max
68+
69+
class Solution {
70+
public:
71+
int arrayNesting(std::vector<int>& nums) {
72+
int res = 0;
73+
int n = nums.size();
74+
std::vector<bool> visited(n, false);
75+
76+
for (int i = 0; i < n; i++) {
77+
if (!visited[i]) {
78+
int start = nums[i], count = 0;
79+
do {
80+
start = nums[start];
81+
count++;
82+
visited[start] = true;
83+
} while (start != nums[i]);
84+
res = std::max(res, count);
85+
}
86+
}
87+
return res;
88+
}
89+
};
90+
91+
92+
```
93+
</TabItem>
94+
<TabItem value="java" label="Java">
95+
<SolutionAuthor name="@Shreyash3087"/>
96+
97+
```java
98+
public class Solution {
99+
public int arrayNesting(int[] nums) {
100+
int res = 0;
101+
for (int i = 0; i < nums.length; i++) {
102+
int start = nums[i], count = 0;
103+
do {
104+
start = nums[start];
105+
count++;
106+
}
107+
while (start != nums[i]);
108+
res = Math.max(res, count);
109+
110+
}
111+
return res;
112+
}
113+
}
114+
```
115+
116+
</TabItem>
117+
<TabItem value="python" label="Python">
118+
<SolutionAuthor name="@Shreyash3087"/>
119+
120+
```python
121+
class Solution:
122+
def arrayNesting(self, nums):
123+
res = 0
124+
visited = [False] * len(nums)
125+
126+
for i in range(len(nums)):
127+
if not visited[i]:
128+
start = nums[i]
129+
count = 0
130+
while True:
131+
start = nums[start]
132+
count += 1
133+
visited[start] = True
134+
if start == nums[i]:
135+
break
136+
res = max(res, count)
137+
138+
return res
139+
```
140+
</TabItem>
141+
</Tabs>
142+
143+
## Complexity Analysis
144+
145+
### Time Complexity: $O(N^2)$
146+
147+
> **Reason**: In worst case, for example- [1,2,3,4,5,0], loop body will be executed $N^2$ times.
148+
149+
### Space Complexity: $O(1)$
150+
151+
> **Reason**: Constant space is used.
152+
153+
### Approach #2 Using Visited Array
154+
#### Algorithm
155+
156+
In the last approach, we observed that in the worst case, all the elements of the nums array are added to the sets corresponding to all the starting indices. But, all these sets correspond to the same set of elements only, leading to redundant calculations.
157+
158+
We consider a simple example and see how this problem can be resolved. From the figure below, we can see that the elements in the current nesting shown by arrows form a cycle. Thus, the same elements will be added to the current set irrespective of the first element chosen to be added to the set out of these marked elements.
159+
160+
![image](https://assets.leetcode.com/static_assets/media/original_images/565/Array_Nesting.PNG)
161+
162+
Thus, when we add an element nums[j] to a set corresponding to any of the indices, we mark its position as visited in a visited array. This is done so that whenever this index is chosen as the starting index in the future, we do not go for redundant count calculations, since we've already considered the elements linked with this index, which will be added to a new(duplicate) set.
163+
164+
By doing so, we ensure that the duplicate sets aren't considered again and again.
165+
166+
Further, we can also observe that no two elements at indices i and j will lead to a jump to the same index k, since it would require nums[i]=nums[j]=k, which isn't possible since all the elements are distinct. Also, because of the same reasoning, no element outside any cycle could lead to an element inside the cycle. Because of this, the use of visited array goes correctly.
167+
168+
## Code in Different Languages
169+
170+
<Tabs>
171+
<TabItem value="cpp" label="C++">
172+
<SolutionAuthor name="@Shreyash3087"/>
173+
174+
```cpp
175+
#include <vector>
176+
#include <algorithm> // For std::max
177+
178+
class Solution {
179+
public:
180+
int arrayNesting(std::vector<int>& nums) {
181+
std::vector<bool> visited(nums.size(), false);
182+
int res = 0;
183+
184+
for (int i = 0; i < nums.size(); i++) {
185+
if (!visited[i]) {
186+
int start = nums[i], count = 0;
187+
do {
188+
start = nums[start];
189+
count++;
190+
visited[start] = true;
191+
} while (start != nums[i]);
192+
res = std::max(res, count);
193+
}
194+
}
195+
return res;
196+
}
197+
};
198+
199+
```
200+
</TabItem>
201+
<TabItem value="java" label="Java">
202+
<SolutionAuthor name="@Shreyash3087"/>
203+
204+
```java
205+
public class Solution {
206+
public int arrayNesting(int[] nums) {
207+
boolean[] visited = new boolean[nums.length];
208+
int res = 0;
209+
for (int i = 0; i < nums.length; i++) {
210+
if (!visited[i]) {
211+
int start = nums[i], count = 0;
212+
do {
213+
start = nums[start];
214+
count++;
215+
visited[start] = true;
216+
}
217+
while (start != nums[i]);
218+
res = Math.max(res, count);
219+
}
220+
}
221+
return res;
222+
}
223+
}
224+
225+
```
226+
227+
</TabItem>
228+
<TabItem value="python" label="Python">
229+
<SolutionAuthor name="@Shreyash3087"/>
230+
231+
```python
232+
class Solution:
233+
def arrayNesting(self, nums):
234+
visited = [False] * len(nums)
235+
res = 0
236+
237+
for i in range(len(nums)):
238+
if not visited[i]:
239+
start = nums[i]
240+
count = 0
241+
while True:
242+
start = nums[start]
243+
count += 1
244+
visited[start] = True
245+
if start == nums[i]:
246+
break
247+
res = max(res, count)
248+
249+
return res
250+
251+
```
252+
</TabItem>
253+
</Tabs>
254+
255+
## Complexity Analysis
256+
257+
### Time Complexity: $O(N)$
258+
259+
> **Reason**: Every element of the nums array will be considered at most once.
260+
261+
### Space Complexity: $O(N)$
262+
263+
> **Reason**: visited array of size N is used.
264+
265+
## References
266+
267+
- **LeetCode Problem**: [Array Nesting](https://leetcode.com/problems/array-nesting/description/)
268+
269+
- **Solution Link**: [Array Nesting](https://leetcode.com/problems/array-nesting/solutions/)

0 commit comments

Comments
 (0)