Skip to content

Improved task 138 #845

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 0 additions & 10 deletions src/main/kotlin/com_github_leetcode/random/Node.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,10 @@ class Node {
var next: Node? = null
var random: Node? = null

constructor() {
`val` = 0
}

constructor(`val`: Int) {
this.`val` = `val`
}

constructor(`val`: Int, next: Node?, random: Node?) {
this.`val` = `val`
this.next = next
this.random = random
}

override fun toString(): String {
val result = StringJoiner(",", "[", "]")
val result2 = StringJoiner(",", "[", "]")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package g0101_0200.s0138_copy_list_with_random_pointer

// #Medium #Top_100_Liked_Questions #Top_Interview_Questions #Hash_Table #Linked_List
// #Programming_Skills_II_Day_14 #Udemy_Linked_List #Top_Interview_150_Linked_List
// #Big_O_Time_O(N)_Space_O(N) #2022_09_03_Time_274_ms_(80.58%)_Space_40.5_MB_(58.99%)
// #Big_O_Time_O(N)_Space_O(N) #2025_07_04_Time_123_ms_(90.70%)_Space_43.99_MB_(97.67%)

import com_github_leetcode.random.Node

Expand All @@ -18,48 +18,19 @@ import com_github_leetcode.random.Node
*/
class Solution {
fun copyRandomList(head: Node?): Node? {
if (head == null) {
return null
val hashMap: MutableMap<Node?, Node> = HashMap()
var cur = head
while (cur != null) {
hashMap.put(cur, Node(cur.`val`))
cur = cur.next
}
// first pass to have a clone node point to the next node. ie A->B becomes A->clonedNode->B
var curr: Node? = head
while (curr != null) {
val clonedNode = Node(curr.`val`)
clonedNode.next = curr.next
curr.next = clonedNode
curr = clonedNode.next
cur = head
while (cur != null) {
val copy: Node = hashMap[cur]!!
copy.next = hashMap[cur.next]
copy.random = hashMap[cur.random]
cur = cur.next
}
curr = head
// second pass to make the cloned node's random pointer point to the orginal node's randome
// pointer.
// ie. A's random pointer becomes ClonedNode's random pointer
while (curr != null) {
if (curr.random != null) {
curr.next?.random = curr.random!!.next
} else {
curr.next?.random = null
}
curr = curr.next?.next
}
curr = head
// third pass to restore the links and return the head of the cloned nodes' list.
var newHead: Node? = null
while (curr != null) {
var clonedNode: Node
if (newHead == null) {
clonedNode = curr.next!!
newHead = clonedNode
} else {
clonedNode = curr.next!!
}
curr.next = clonedNode.next
if (curr.next != null) {
clonedNode.next = curr.next!!.next
} else {
clonedNode.next = null
}
curr = curr.next
}
return newHead
return hashMap[head]
}
}
19 changes: 12 additions & 7 deletions src/test/kotlin/com_github_leetcode/random/NodeTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import org.junit.jupiter.api.Test
internal class NodeTest {
@Test
fun constructor() {
val node = Node()
val node = Node(0)
assertThat(node.`val`, equalTo(0))
assertThat(node.toString(), equalTo("[[0,null]]"))
}
Expand All @@ -21,18 +21,23 @@ internal class NodeTest {

@Test
fun constructor3() {
val node = Node(1, Node(2), Node(3))
val node = Node(1)
node.next = Node(2)
node.random = Node(3)
assertThat(node.`val`, equalTo(1))
assertThat(node.toString(), equalTo("[[1,3],[2,null]]"))
}

@Test
fun constructor4() {
val node = Node(
1,
Node(2, Node(21), Node(22)),
Node(3, null, Node(32)),
)
val next = Node(2)
next.next = Node(21)
next.random = Node(22)
val random = Node(3)
random.random = Node(32)
val node = Node(1)
node.next = next
node.random = random
assertThat(node.`val`, equalTo(1))
assertThat(node.toString(), equalTo("[[1,3],[2,2],[21,null]]"))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ internal class SolutionTest {
node11.random = node1
node10.random = node11
node1.random = node7
assertThat(Solution().copyRandomList(node7).toString(), equalTo("[[7,null],[13,0],[11,4],[10,2],[1,0]]"))
assertThat(
Solution().copyRandomList(node7).toString(),
equalTo("[[7,null],[13,0],[11,4],[10,2],[1,0]]"),
)
}

@Test
Expand All @@ -34,7 +37,10 @@ internal class SolutionTest {
node1.random = node1
node2.next = null
node2.random = node2
assertThat(Solution().copyRandomList(node1).toString(), equalTo("[[1,1],[2,1]]"))
assertThat(
Solution().copyRandomList(node1).toString(),
equalTo("[[1,1],[2,1]]"),
)
}

@Test
Expand All @@ -48,6 +54,9 @@ internal class SolutionTest {
node32.random = node31
node33.next = null
node33.random = null
assertThat(Solution().copyRandomList(node31).toString(), equalTo("[[3,null],[3,0],[3,null]]"))
assertThat(
Solution().copyRandomList(node31).toString(),
equalTo("[[3,null],[3,0],[3,null]]"),
)
}
}