【leetcode】565. Array Nesting
阿新 • • 發佈:2021-11-20
You are given an integer arraynumsof lengthnwherenumsis a permutation of the numbers in the range[0, n - 1].
You should build a sets[k] = {nums[k], nums[nums[k]], nums[nums[nums[k]]], ... }subjected to the following rule:
- The first element ins[k]starts with the selection of the elementnums[k]ofindex = k.
- The next element ins[k]should benums[nums[k]], and thennums[nums[nums[k]]], and so on.
- We stop adding right before a duplicate element occurs ins[k].
classSolution { 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陣列進行儲存
classSolution { 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; } };