Loading

【leetcode】565. Array Nesting

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].
 
1、暴力求解方法: 时间复杂度高了 超时了
class Solution {
public:
    int arrayNesting(vector<int>& nums) {
        //先用暴力法写 这样写时间复杂度太高了 相当于o(n^2)
        int n=nums.size();
        int len=INT_MIN;
        for(int i=0;i<n;++i)
        {
            unordered_set<int> res;
            int index=i;
            while(!res.count(nums[index]))
            {
                res.insert(nums[index]);
                index=nums[index];
            }
             len=max(len,(int)res.size());
        }
        return len;
    }
};

  

  分析:暴力法是对nums中的每一个数字 都作为起始数字开始 进行array nesting 嵌套 
   对于已经遍历过的数字就不需要让他作为开头进行遍历 因为其之后的检索路径已经是之前的一个子集合
  同时检索的过程中 也不需要set 只需要存头数字 如果当前数字和头数字一样那么就结束 了
    
2、按照这两个思路 对代码进行优化 用一个dp数组进行存储
class Solution {
public:
    int arrayNesting(vector<int>& nums) {
        //先用暴力法写 这样写时间复杂度太高了 相当于o(n^2)
        int n=nums.size();
        int len=INT_MIN;
        unordered_set<int> dp;//用于存储哪些结点已经访问过了
        for(int i=0;i<n;++i)
        {
            int index=i;
            if(dp.count(index)) continue;
            //dp.insert(index); //没有访问存储当前路径
            unordered_set<int> res;
            while(!res.count(nums[index]))
            {
                res.insert(nums[index]);
                dp.insert(index);
                index=nums[index];
            }
             len=max(len,(int)res.size());
        
        }
        return len;
    }
};

3、取消存储数据的 res 直接存访问的头结点

class Solution {
public:
    int arrayNesting(vector<int>& nums) {
        //先用暴力法写 这样写时间复杂度太高了 相当于o(n^2)
        int n=nums.size();
        int len=INT_MIN;
        unordered_set<int> dp;//用于存储哪些结点已经访问过了
        for(int i=0;i<n;++i)
        {
            int index=i;
            if(dp.count(index)) continue;
            //dp.insert(index); //没有访问存储当前路径
            int front=index;
            int tmp_len=1;
            while(front!=nums[index])
            {
                //res.insert(nums[index]);
                dp.insert(index);
                index=nums[index];
                tmp_len++;
            }
             len=max(len,tmp_len);
        }
        return len;
    }
};

 

posted @ 2021-11-19 21:49  aalanwyr  阅读(20)  评论(0编辑  收藏  举报