[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 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:
- N is an integer within the range [1, 20,000].
- The elements of A are all distinct.
- 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
类似题目:
参考资料:
https://leetcode.com/problems/array-nesting/
https://leetcode.com/problems/array-nesting/discuss/102432/C%2B%2B-Java-Clean-Code-O(N)
LeetCode All in One 题目讲解汇总(持续更新中...)
[LeetCode] 565. Array Nesting 数组嵌套的更多相关文章
- [LeetCode] Array Nesting 数组嵌套
A zero-indexed array A consisting of N different integers is given. The array contains all integers ...
- 【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 ...
- 【LeetCode】565. Array Nesting 解题报告(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...
- [LeetCode] Patching Array 补丁数组
Given a sorted positive integer array nums and an integer n, add/patch elements to the array such th ...
- [LeetCode] Rotate Array 旋转数组
Rotate an array of n elements to the right by k steps. For example, with n = 7 and k = 3, the array ...
- [LeetCode] Contiguous Array 邻近数组
Given a binary array, find the maximum length of a contiguous subarray with equal number of 0 and 1. ...
- LeetCode Rotate Array 翻转数组
题意:给定一个数组,将该数组的后k位移动到前n-k位之前.(本题在编程珠玑中第二章有讲) 思路: 方法一:将后K位用vector容器装起来,再移动前n-k位到后面,再将容器内k位插到前面. class ...
- 565. Array Nesting
Problem statement: A zero-indexed array A consisting of N different integers is given. The array con ...
- Java实现 LeetCode 565 数组嵌套(没有重复值的数组)
565. 数组嵌套 索引从0开始长度为N的数组A,包含0到N - 1的所有整数.找到并返回最大的集合S,S[i] = {A[i], A[A[i]], A[A[A[i]]], - }且遵守以下的规则. ...
随机推荐
- vue+element 动态表单验证
公司最近的项目有个添加动态表单的需求,总结一下我在表单验证上遇到的一些坑. 如图是功能的需求,这个功能挺好实现的,但是表单验证真是耗费了我一些功夫. vue+element在表单验证上有一些限制,必须 ...
- jQuery 源码分析(二) 入口模块
jQuery返回的对象本质上是一个JavaScript对象,而入口模块则可以保存对应的节点的引用,然后供其它模块操作 我们创建jQuery对象时可以给jQuery传递各种不同的选择器,如下: fals ...
- 1.go语言入门
1.Go语言中文网,选择相应版本(32位或64位)下载 https://studygolang.com/dl, 2.解压到一个任意文件夹 3.配置环境变量 cmd命令行输入go version查看当前 ...
- div+css画一个小猪佩奇
用DIV+CSS画一个小猪佩奇,挺可爱的,嘻嘻. HTML部分(全是DIV) <!-- 小猪佩奇整体容器 --> <div class="pig_container&quo ...
- 也作一下装配脑袋的Expression习题【转】
一.习题 http://www.cnblogs.com/Ninputer/archive/2009/08/28/expression_tree1.html 二.参考 http://msdn.micro ...
- 你必须知道的EF知识和经验(转)
注意:以下内容如果没有特别申明,默认使用的EF6.0版本,code first模式. 推荐MiniProfiler插件 工欲善其事,必先利其器. 我们使用EF和在很大程度提高了开发速度,不过随之带来的 ...
- 关于Idea突然无法输入的诡异问题解决
问题描述 最近加班把自己的装有Debian的笔记本带到公司,使用Idea写代码的时候,突然间无法输入,ctrl与tab还可用,重启Idea能得到一阵的解决 解决参考 如果是Linux平台,请考虑是否是 ...
- C#,二分法,BinarySearch()
static int BinarySearch(int[] arr,int key,int low,int high) { low = 0;high = arr.Length - 1; while(l ...
- JavaScript 设计模式分类
设计模式的目的是为了提高代码的整洁性.降低代码的资源占用量. JS中的设计模式可分为以下三种: 1. 创建型设计模式 说明:专注于处理对象创建的机制,以合适的方式创建对象,以此来降低创建对象过程的复杂 ...
- 进程调度算法spf,fpf,时间片轮转算法实现
调度的基本概念:从就绪队列中按照一定的算法选择一个进程并将处理机分配给它运行,以实现进程并发地执行. 进程信息 struct node { string name;//进程名称 int id;//进程 ...