【LeetCode】457. Circular Array Loop 解题报告(C++)

作者: 负雪明烛
id: fuxuemingzhu
个人博客: http://fuxuemingzhu.cn/


题目地址:https://leetcode.com/problems/circular-array-loop/

题目描述

You are given a circular array nums of positive and negative integers. If a number k at an index is positive, then move forward k steps. Conversely, if it’s negative (-k), move backward k steps. Since the array is circular, you may assume that the last element’s next element is the first element, and the first element’s previous element is the last element.

Determine if there is a loop (or a cycle) in nums. A cycle must start and end at the same index and the cycle’s length > 1. Furthermore, movements in a cycle must all follow a single direction. In other words, a cycle must not consist of both forward and backward movements.

Example 1:

Input: [2,-1,1,2,2]
Output: true
Explanation: There is a cycle, from index 0 -> 2 -> 3 -> 0. The cycle's length is 3.

Example 2:

Input: [-1,2]
Output: false
Explanation: The movement from index 1 -> 1 -> 1 ... is not a cycle, because the cycle's length is 1. By definition the cycle's length must be greater than 1.

Example 3:

Input: [-2,1,-1,-2,-2]
Output: false
Explanation: The movement from index 1 -> 2 -> 1 -> ... is not a cycle, because movement from index 1 -> 2 is a forward movement, but movement from index 2 -> 1 is a backward movement. All movements in a cycle must follow a single direction.

Note:

  1. -1000 ≤ nums[i] ≤ 1000
  2. nums[i] ≠ 0
  3. 1 ≤ nums.length ≤ 5000

Follow up:

Could you solve it in O(n) time complexity and O(1) extra space complexity?

题目大意

有一个首尾相接的环形数组,问从任何一个位置i开始走,每次走的步长是nums[i],而且每次走的时候要么从左向后走,要么走后向前走,总之只沿着一个方向走,能不能形成一个环。要求环的大小 > 1.

解题方法

快慢指针

读题的时候应该意识到和链表有环非常的像,所以可以使用快慢指针,一个走两步,一个走一步,如果相遇说明有环。

这个题难点在于只能沿着一个方向走,所以在每次循环的过程中,必须保证所经历过的所有数字都是同号的,那么在快指针经历过的每个位置都要判断一下和出发点的数字是不是相同的符号,也就是while循环的判断部分。

如果快慢指针相遇的时候,还要判断环的大小不是1,所以,如果相遇点的位置如果再走一步是自己那么也是不行的。如果环的大小不是1,就可以返回True了。

每次移动的时候,慢指针走一步,快指针向后走两步。

Python代码如下:

class Solution(object):
    def circularArrayLoop(self, nums):
        """
        :type nums: List[int]
        :rtype: bool
        """
        N, self.nums = len(nums), nums
        for i in range(N):
            slow = i
            fast = self.nextpos(slow)
            while nums[fast] * nums[i] > 0 and nums[self.nextpos(fast)] * nums[i] > 0:
                if fast == slow:
                    if slow == self.nextpos(slow):
                        break
                    return True
                slow = self.nextpos(slow)
                fast = self.nextpos(self.nextpos(fast))
        return False
    
    def nextpos(self, index):
        N = len(self.nums)
        return (index + self.nums[index] + N) % N

日期

2019 年 2 月 27 日 —— 二月就要完了

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页