Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[LeetCode] 565. Array Nesting #565

Open
grandyang opened this issue May 30, 2019 · 0 comments
Open

[LeetCode] 565. Array Nesting #565

grandyang opened this issue May 30, 2019 · 0 comments

Comments

@grandyang
Copy link
Owner

grandyang commented May 30, 2019

 

You are given an integer array nums of length n where nums is a permutation of the numbers in the range [0, n - 1].

You should build a set s[k] = {nums[k], nums[nums[k]], nums[nums[nums[k]]], ... } subjected to the following rule:

  • The first element in s[k] starts with the selection of the element nums[k] of index = k.
  • The next element in s[k] should be nums[nums[k]], and then nums[nums[nums[k]]], and so on.
  • We stop adding right before a duplicate element occurs in s[k].

Return  the longest length of a set  s[k].

 

Example 1:

Input: nums = [5,4,0,3,1,6,2]
Output: 4
Explanation: 
nums[0] = 5, nums[1] = 4, nums[2] = 0, nums[3] = 3, nums[4] = 1, nums[5] = 6, nums[6] = 2.
One of the longest sets s[k]:
s[0] = {nums[0], nums[5], nums[6], nums[2]} = {5, 6, 2, 0}

Example 2:

Input: nums = [0,1,2]
Output: 1

 

Constraints:

  • 1 <= nums.length <= 105
  • 0 <= nums[i] < nums.length
  • All the values of nums are unique.

 

这道题让我们找嵌套数组的最大个数,给的数组总共有n个数字,范围均在 [0, n-1] 之间,题目中也把嵌套数组的生成解释的很清楚了,其实就是值变成坐标,得到的数值再变坐标。那么实际上当循环出现的时候,嵌套数组的长度也不能再增加了,而出现的这个相同的数一定是嵌套数组的首元素(因为这些数字没有重复,所以不可能在其他位置也有一个数指向同一个下标),博主刚开始没有想清楚这一点,以为出现重复数字的地方可能是嵌套数组中间的某个位置,于是用个 set 将生成的嵌套数组存入,然后每次查找新生成的数组是否已经存在。而且还以原数组中每个数字当作嵌套数组的起始数字都算一遍,结果当然是 TLE 了。其实对于遍历过的数字,我们不用再将其当作开头来计算了,而是只对于未遍历过的数字当作嵌套数组的开头数字,不过在进行嵌套运算的时候,并不考虑中间的数字是否已经访问过,而是只要找到和起始位置相同的数字位置,然后更新结果 res,参见代码如下:

 

解法一:

class Solution {
public:
    int arrayNesting(vector<int>& nums) {
        int n = nums.size(), res = INT_MIN;
        vector<bool> visited(n, false);
        for (int i = 0; i < nums.size(); ++i) {
            if (visited[nums[i]]) continue;
            res = max(res, helper(nums, i, visited));
        }
        return res;
    }
    int helper(vector<int>& nums, int start, vector<bool>& visited) {
        int i = start, cnt = 0;
        while (cnt == 0 || i != start) {
            visited[i] = true;
            i = nums[i];
            ++cnt;
        }
        return cnt;
    }
};

 

下面这种方法写法上更简洁一些,思路完全一样,参见代码如下:

 

解法二:

class Solution {
public:
    int arrayNesting(vector<int>& nums) {
        int n = nums.size(), res = INT_MIN;
        vector<bool> visited(n, false);
        for (int i = 0; i < n; ++i) {
            if (visited[nums[i]]) continue;
            int cnt = 0, j = i;
            while(cnt == 0 || j != i) {
                visited[j] = true;
                j = nums[j];
                ++cnt;
            }
            res = max(res, cnt);
        }
        return res;
    }
};

 

下面这种解法是网友 @edyyy 提醒博主的,可以优化解法二的空间,我们并不需要专门的数组来记录数组是否被遍历过,而是在遍历的过程中,将其交换到其应该出现的位置上,因为如果某个数出现在正确的位置上,那么它一定无法组成嵌套数组,这样就相当于我们标记了其已经访问过了,思路确实很赞啊,参见代码如下:

 

解法三:

class Solution {
public:
    int arrayNesting(vector<int>& nums) {
        int n = nums.size(), res = 0;
        for (int i = 0; i < n; ++i) {
            int cnt = 1;
            while (nums[i] != i) {
                swap(nums[i], nums[nums[i]]);
                ++cnt;
            }
            res = max(res, cnt);
        }
        return res;
    }
};

 

Github 同步地址:

#565

 

类似题目:

Nested List Weight Sum II

Flatten Nested List Iterator 

Nested List Weight Sum

 

参考资料:

https://leetcode.com/problems/array-nesting/

https://leetcode.com/problems/array-nesting/discuss/102432/C%2B%2B-Java-Clean-Code-O(N)

https://leetcode.com/problems/array-nesting/discuss/232283/C%2B%2B-straightforward-solution-beats-100

 

LeetCode All in One 题目讲解汇总(持续更新中...)

喜欢请点赞,疼爱请打赏❤️~.~

微信打赏

|

Venmo 打赏


---|---

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant