Skip to content

Commit 6c4f93f

Browse files
author
ivan
committed
dev calculateCircleLength and findCircleEntrance
1 parent a751692 commit 6c4f93f

File tree

2 files changed

+95
-5
lines changed

2 files changed

+95
-5
lines changed

scala/src/main/scala/ch07_linkedlist/LinkedListAlgo.scala

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ package ch07_linkedlist
22

33
import ch06_linkedlist.Node
44

5+
import scala.util.control.Breaks._
6+
57
object LinkedListAlgo {
68

79
//reverse a linked list
@@ -27,7 +29,12 @@ object LinkedListAlgo {
2729
current.get
2830
}
2931

30-
def checkCircle(head: Node): Boolean = {
32+
/**
33+
*
34+
* @param head
35+
* @return Some(Node) a node in a circle or None
36+
*/
37+
def checkCircle(head: Node): Option[Node] = {
3138
var fast = head
3239
var slow = head
3340

@@ -36,10 +43,47 @@ object LinkedListAlgo {
3643
slow = slow.next.get
3744

3845
if (fast.equals(slow)) {
39-
return true
46+
return Some(slow)
4047
}
4148
}
42-
false
49+
None
50+
}
51+
52+
/**
53+
* calculate the length of the circle
54+
*
55+
* @param node - some node in the circle
56+
* @return circle length
57+
*/
58+
def calculateCircleLength(node: Node): Int = {
59+
var length = 1
60+
var cursor = node.next.get
61+
62+
while (cursor != node) {
63+
length += 1
64+
cursor = cursor.next.get
65+
}
66+
67+
length
68+
}
69+
70+
def findCircleEntrance(head: Node): Option[Node] = {
71+
checkCircle(head).map(node => {
72+
val length = calculateCircleLength(node)
73+
var fast = head
74+
var slow = head
75+
//fast move length steps
76+
for (i <- 0 until length) {
77+
fast = fast.next.get
78+
}
79+
80+
while (slow != fast) {
81+
fast = fast.next.get
82+
slow = slow.next.get
83+
}
84+
85+
slow
86+
})
4387
}
4488

4589
//assuming nodeA and nodeB are all sorted list in ascending order

scala/src/test/scala/ch07_linkedlist/LinkedListAlgoTest.scala

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ class LinkedListAlgoTest extends FlatSpec with Matchers {
5050
node5.next = Some(node6)
5151
node6.next = Some(node3)
5252

53-
assert(LinkedListAlgo.checkCircle(node1))
53+
assert(LinkedListAlgo.checkCircle(node1).isDefined)
5454
}
5555

5656
it should "check circle for none circled linked list" in {
@@ -70,7 +70,53 @@ class LinkedListAlgoTest extends FlatSpec with Matchers {
7070
node4.next = Some(node5)
7171
node5.next = Some(node6)
7272

73-
assert(!LinkedListAlgo.checkCircle(node1))
73+
assert(LinkedListAlgo.checkCircle(node1).isEmpty)
74+
}
75+
76+
it should "calculate circle length" in {
77+
val node1 = new Node(1, None)
78+
val node2 = new Node(2, None)
79+
val node3 = new Node(3, None)
80+
val node4 = new Node(4, None)
81+
val node5 = new Node(5, None)
82+
val node6 = new Node(6, None)
83+
84+
//1->2->3->4->5->6->3 it's a circle
85+
//node1 is the head
86+
node1.next = Some(node2)
87+
node2.next = Some(node3)
88+
node3.next = Some(node4)
89+
node4.next = Some(node5)
90+
node5.next = Some(node6)
91+
node6.next = Some(node3)
92+
93+
val node = LinkedListAlgo.checkCircle(node1).get
94+
95+
val length = LinkedListAlgo.calculateCircleLength(node)
96+
97+
length should equal(4)
98+
}
99+
100+
it should "find entrance of the circle" in {
101+
val node1 = new Node(1, None)
102+
val node2 = new Node(2, None)
103+
val node3 = new Node(3, None)
104+
val node4 = new Node(4, None)
105+
val node5 = new Node(5, None)
106+
val node6 = new Node(6, None)
107+
108+
//1->2->3->4->5->6->3 it's a circle
109+
//node1 is the head
110+
node1.next = Some(node2)
111+
node2.next = Some(node3)
112+
node3.next = Some(node4)
113+
node4.next = Some(node5)
114+
node5.next = Some(node6)
115+
node6.next = Some(node3)
116+
117+
val node = LinkedListAlgo.findCircleEntrance(node1)
118+
119+
node.get.data should equal(3)
74120
}
75121

76122
it should "merge 2 sorted list into 1" in {

0 commit comments

Comments
 (0)