A zero-indexed array A of length N contains all integers from 0 to N-1. Find and return the longest length of set S, where S[i] = {A[i], A[A[i]], A[A[A[i]]], ... } subjected to the rule below.

Suppose the first element in S starts with the selection of element A[i] of index = i, the next element in S should be A[A[i]], and then A[A[A[i]]]… By that analogy, we stop adding right before a duplicate element occurs in S.

Example 1:

Input: A = [5,4,0,3,1,6,2]
Output: 4
Explanation:
A[0] = 5, A[1] = 4, A[2] = 0, A[3] = 3, A[4] = 1, A[5] = 6, A[6] = 2. One of the longest S[K]:
S[0] = {A[0], A[5], A[6], A[2]} = {5, 6, 2, 0}

Note:

  1. N is an integer within the range [1, 20,000].
  2. The elements of A are all distinct.
  3. Each element of A is an integer within the range [0, N-1].

这道题让我们找嵌套数组的最大个数,给的数组总共有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 = ; 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 = ;
while (cnt == || 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 = ; i < n; ++i) {
if (visited[nums[i]]) continue;
int cnt = , j = i;
while(cnt == || 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 = ;
for (int i = ; i < n; ++i) {
int cnt = ;
while (nums[i] != i) {
swap(nums[i], nums[nums[i]]);
++cnt;
}
res = max(res, cnt);
}
return res;
}
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/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 题目讲解汇总(持续更新中...)

[LeetCode] Array Nesting 数组嵌套的更多相关文章

  1. [LeetCode] 565. Array Nesting 数组嵌套

    A zero-indexed array A of length N contains all integers from 0 to N-1. Find and return the longest ...

  2. leetcode 442. Find All Duplicates in an Array 查找数组中的所有重复项

    https://leetcode.com/problems/find-all-duplicates-in-an-array/description/ 参考:http://www.cnblogs.com ...

  3. 【leetcode】565. Array Nesting

    You are given an integer array nums of length n where nums is a permutation of the numbers in the ra ...

  4. Leetcode 565.数组嵌套

    数组嵌套 索引从0开始长度为N的数组A,包含0到N - 1的所有整数.找到并返回最大的集合S,S[i] = {A[i], A[A[i]], A[A[A[i]]], ... }且遵守以下的规则. 假设选 ...

  5. Java实现 LeetCode 565 数组嵌套(没有重复值的数组)

    565. 数组嵌套 索引从0开始长度为N的数组A,包含0到N - 1的所有整数.找到并返回最大的集合S,S[i] = {A[i], A[A[i]], A[A[A[i]]], - }且遵守以下的规则. ...

  6. C#LeetCode刷题-数组

    数组篇 # 题名 刷题 通过率 难度 1 两数之和 C#LeetCode刷题之#1-两数之和(Two Sum) 43.1% 简单 4 两个排序数组的中位数 C#LeetCode刷题之#4-两个排序数组 ...

  7. leetcode array解题思路

    Array *532. K-diff Pairs in an Array 方案一:暴力搜索, N平方的时间复杂度,空间复杂度N 数组长度为10000,使用O(N平方)的解法担心TLE,不建议使用,尽管 ...

  8. golang之 Array(数组)

    目录 一.Array(数组) 二.数组的定义 1. 基本语法 三.数组的初始化 1. 方式一 2. 方式二 3. 方式三 四.数组的遍历 1. 方式一:for循环遍历 2. 方式二:for range ...

  9. go实现json数组嵌套

    go实现json数组嵌套 引用包 "encoding/json" 定义以下结构体 type person struct { Name string `json:"name ...

随机推荐

  1. shiro权限框架(三)

    三.身份验证 身份验证,即在应用中谁能证明他就是他本人.一般提供如他们的身份 ID 一些标识信息来表明他就是他本人,如提供身份证,用户名/密码来证明 在 shiro 中,用户需要提供 principa ...

  2. KVM之一:安装准备(基于CentOS6.7)

    KVM 虚拟机简介: Kernel-based Virtual Machine的简称,是一个开源的系统虚拟化模块,自Linux 2.6.20之后集成在Linux的各个主要发行版本中.它使用Linux自 ...

  3. /var/spool/clientmqueue目录下存在大量文件的原因及解决方法

    问题现象:linux操作系统中的/var/spool/clientmqueue/目录下存在大量文件.原因分析: 系统中有用户开启了cron,而cron中执行的程序有输出内容,输出内容会以邮件形式发给c ...

  4. tomcat超时、内存不足

    1.Tomcat 启动超过45s启动失败,报超时错误 可以Eclipse 下Tomcat中扩大tomcat启动时间,默认为45 ,修改为245 2 . tomcat启动内存不足 Run - Run C ...

  5. 关于伪类after后续追加,实现js事件(如点击事件)

    实现情况为:点击"编辑"后,"编辑"文字变成"完成",再点击伪类元素后的"完成",此时的"完成"应该 ...

  6. Alpha冲刺置顶随笔

    项目名称:城市安全风险管控系统 小组成员: 张梨贤.林静.周静平.黄腾飞 Alpha冲刺随笔 Alpha冲刺Day1:http://www.cnblogs.com/linlkg/p/7896980.h ...

  7. nyoj 擅长排列的小名II

    擅长排列的小明 II 时间限制:1000 ms  |           内存限制:65535 KB 难度:3   描述 小明十分聪明,而且十分擅长排列计算. 有一天小明心血来潮想考考你,他给了你一个 ...

  8. Node入门教程(5)第四章:global 全局变量

    global - 全局变量 全局对象(global object),不要和 全局的对象( global objects )或称标准内置对象混淆.这里说的全局的对象是说在全局作用域里的内的对象.全局作用 ...

  9. 浏览器端类EXCEL表格插件 - 智表ZCELL产品V1.0.0.1版本发布

    智表的优势 智表兼容与依赖 ZCELL 基于jQuery V1.11.3版本研发,兼容性依赖于jQuery自身的兼容性. 经过验证,目前IE.火狐.谷歌.360等主流浏览器均可以正常使用. 智表下载 ...

  10. 前端基础之html-Day12

    1.web服务本质 import socket def main(): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.bi ...