图解leetcode565. 数组嵌套

1.题目描述:

索引从0开始长度为N的数组A,包含0到N - 1的所有整数。找到最大的集合S并返回其大小,其中 S[i] = {A[i], A[A[i]], A[A[A[i]]], ... }且遵守以下的规则。假设选择索引为i的元素A[i]为S的第一个元素,S的下一个元素应该是A[A[i]],之后是A[A[A[i]]]... 以此类推,不断添加直到S出现重复的元素。

2.暴力解法:

直接所有数组元素遍历,得到每个S集合的长度取得最大值即可,双层for循环,最差情况时间复杂度能达到O(n^2),提交之后会超出时间限制,代码如下:

class Solution {
    public int arrayNesting(int[] nums) {
        int maxLen = 0;
        int count; 
        for(int i = 0;i < nums.length; i++){
            int[] arr = new int[nums.length];
            //使用arr数组来确认集合S是否出现重复元素,0代表未访问,1代表已访问
            count = 0;
            while(arr[nums[i]] == 0){
                arr[nums[i]] = 1;
                i = nums[i];
                count++;
            }
            maxLen = Math.max(count,maxLen);
        }
        return maxLen;
    }
}

3.对暴力解法进行优化:

来以示例数组[5,4,0,3,1,6,2]为例,寻找此解题的内涵规律,图解如下。

代码只需要移动定义arr数组到循环外即可,这样相当于所有环走遍之后走了nums数组的长度,时间复杂度为O(n)。

class Solution {
    public int arrayNesting(int[] nums) {
        int maxLen = 0;
        int count;
        int[] arr = new int[nums.length];
        //使用arr数组来确认集合S是否出现重复元素,0代表未访问,1代表已访问 
        for(int i = 0;i < nums.length; i++){
            count = 0;
            while(arr[nums[i]] == 0){
                arr[nums[i]] = 1;
                i = nums[i];
                count++;
            }
            maxLen = Math.max(count,maxLen);
        }
        return maxLen;
    }
}

继续优化:可以直接在原数组上进行访问的判定,将访问过的元素置为Integer.MAX_VALUE。

class Solution {
    public int arrayNesting(int[] nums) {
        int maxLen = 0;
        int count;
        int temp;
        for(int i = 0;i < nums.length; i++){
            count = 0;
            while(nums[i] != Integer.MAX_VALUE){
                temp = i;
                i = nums[i];
                nums[temp] = Integer.MAX_VALUE;
                count++;
            }
            maxLen = Math.max(count,maxLen);
        }
        return maxLen;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值