알고리즘풀이
Leetcode: Linked List Cycle, 연결 리스트 순환 판별
batterflyyin
2021. 2. 13. 09:51
문제설명
- 연결 리스트의 head가 주어졌을 때, 리스트가 순환하는지 판별하라
문제풀이
- fast runner, slow runner 이중 포인터 방법을 사용한다.
- slow runner는 노드를 한 번씩 이동하고, fast runner는 노드를 두 번씩 이동한다.
- 리스트가 순환이라면, slow runner와 fast runner는 반드시 만난다.
public class ListNode {
public var val: Int
public var next: ListNode?
public init() { self.val = 0; self.next = nil; }
public init(_ val: Int) { self.val = val; self.next = nil; }
public init(_ val: Int, _ next: ListNode?) { self.val = val; self.next = next; }
}
extension ListNode {
func strings() -> String {
if let nextNode = next {
return "\(val) -> \(nextNode.strings())"
} else {
return "\(val)"
}
}
}
extension ListNode {
static func from(arr: [Int]) -> ListNode? {
var node = ListNode(0)
let head = node
for element in arr {
let newNode = ListNode(element)
node.next = newNode
node = newNode
}
return head.next
}
}
// Answer
func hasCycle(_ head: ListNode?) -> Bool {
var slow = head
var fast = head?.next
while let slowNode = slow, let fastNode = fast {
if slowNode === fastNode {
return true
}
slow = slowNode.next
fast = fastNode.next?.next
}
return false
}
// TEST
var node1: ListNode, node2: ListNode, node3: ListNode, node4: ListNode
// case 1 head = [1,2], pos = 0
node1 = ListNode(1)
node2 = ListNode(2)
node1.next = node2
node2.next = node2
print(hasCycle(node1)) // true
// case 2 head = [1], pos = -1
node1 = ListNode(1)
print(hasCycle(node1)) // false
// case 3 head = [3,2,0,4], pos = 1
node1 = ListNode(3)
node2 = ListNode(2)
node3 = ListNode(0)
node4 = ListNode(4)
node1.next = node2
node2.next = node3
node3.next = node4
node4.next = node2
print(hasCycle(node1)) // true