leetcode(565). Array Nesting

problem

A zero-indexed array A consisting of N different integers is given.
The array contains all integers in the range [0, N - 1].

Sets S[K] for 0 <= K < N are defined as follows:

S[K] = { A[K], A[A[K]], A[A[A[K]]], … }.

Sets S[K] are finite for each K and should NOT contain duplicates.

Write a function that given an array A consisting of N integers,
return the size of the largest set S[K] for this array.
Note:

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

solution

这个问题中所提到的定义很像抽象代数中的循环群,只不过已经很久没学了,具体使用的数学工具已经忘得差不多了,所以在这里只使用了一些编程的技巧来解答这个问题,题中想要找出最长的S[k],我们可以发现S[k]都可以构成一个循环,因此我们可以使用python中的set这个数据结构,来完成这个任务,思路就是使用main_set 来表示所有已遍历过的数字
,使用tmp_set 来保存这次的遍历数字,那么tmp_set 的最大值就是要求的结果,超过了14%的提交。

class Solution(object):
    def arrayNesting(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        n = len(nums)
        main_set = set()
        tmp_set = set()
        ans = 0
        for i in range(n):
            if not i in main_set:
                t = i
                m = 0
                while not t in tmp_set:
                    tmp_set.add(t)
                    t = nums[t]
                    m += 1
                main_set = main_set | tmp_set
                print(m)
                ans = max(ans, m)
            else:
                continue

        return ans

在写这篇博客的时候感觉可以只需要一个set就可以,经过优化以后超过了89%的提交。

class Solution(object):
    def arrayNesting(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        n = len(nums)
        main_set = set()
        ans = 0

        for i in range(n):
            if nums[i] not in main_set:
                tmp = 0
                t = nums[i]
                while t not in main_set:
                    main_set.add(t)
                    tmp += 1
                    t = nums[t]
                ans = max(ans, tmp)
            else:
                continue
        return ans

在上面的代码中使用set作为标记是否遍历过的数据结构,实际上对于这个任务完全可以使用visited=list()来标记,只不过实际上set的时间复杂度也是O(1)所以就不在这方面进行优化了(这里就是使用数据结构代替想法)。

上面的这个想法就是新建一个与原数组相同长度的标记数组来标记已遍历元素,而实际上在这个问题中元素遍历过一次之后就没用了,因此可以不使用额外的空间来解决这个问题,也就是说遍历之后就把数字设置为原来不存在的数字作为标记(N is an integer within the range [1, 20,000].),这个想法时间上提升应该不大,因为只是标记方式改变了,但是空间上将原来的 O(n) 降为了 O(1)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值