-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathintersect.go
145 lines (113 loc) · 2.79 KB
/
intersect.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package main
/*
Given two singly linked lists that intersect at some point,
find the intersecting node.
The lists are non-cyclical.
For example,
given A = 3 -> 7 -> 8 -> 10 and B = 99 -> 1 -> 8 -> 10,
return the node with value 8.
In this example,
assume nodes with the same value are the exact same node objects.
Do this in O(M + N) time (where M and N are the lengths of the lists)
and constant space.
*/
import (
"fmt"
"log"
"os"
"strconv"
"linked_lists/list"
)
func main() {
if len(os.Args) < 2 {
fmt.Printf("intersection of 2 linked lists\n")
fmt.Printf("usage: %s <intersectionvalue> n1.0 ... -- n2.0 ...\n", os.Args[0])
return
}
intersectionValue, err := strconv.Atoi(os.Args[1])
if err != nil {
log.Fatal(err)
}
fmt.Printf("Insecting lists at node value %d\n", intersectionValue)
lists := list.MultiCompose(os.Args[2:])
if len(lists) > 2 {
log.Fatal("require only 2 lists\n")
}
fmt.Printf("Found %d lists\n", len(lists))
for _, l := range lists {
list.Print(l)
fmt.Println()
}
if !createIntersection(intersectionValue, lists[0], lists[1]) {
fmt.Printf("lists did not intersect\n")
return
}
fmt.Printf("After creating an intersection:\n")
for _, l := range lists {
list.Print(l)
fmt.Println()
}
intersectingNode := findIntersection(lists[0], lists[1])
if intersectingNode == nil {
fmt.Printf("Did not find intersection\n")
return
}
fmt.Printf("Intersecting node at %p, value %d\n", intersectingNode, intersectingNode.Data)
}
// findIntersection looks through 2 linked lists to find the node
// at which they intersect.
func findIntersection(hd1, hd2 *list.Node) *list.Node {
len1 := listLength(hd1)
len2 := listLength(hd2)
for len1 > len2 {
hd1 = hd1.Next
len1--
}
for len2 > len1 {
hd2 = hd2.Next
len2--
}
var intersection *list.Node
for n1, n2 := hd1, hd2; n1 != nil && n2 != nil; n1, n2 = n1.Next, n2.Next {
// comparing pointer equality of nodes, not data value of nodes
if n1 == n2 {
intersection = n1
break
}
}
return intersection
}
func listLength(head *list.Node) int {
m := 0
for p := head; p != nil; p = p.Next {
m++
}
return m
}
// createIntersection puts the 2 lists (lists[0] and lists[1])
// together at a node in each with value intersectionValue
// Won't do this correcti if either head node has the value
// of the desired intersection
func createIntersection(intersectionValue int, hd0, hd1 *list.Node) bool {
var before0, before1 *list.Node
for node := hd0; node != nil; node = node.Next {
if node.Data == intersectionValue {
break
}
before0 = node
}
if before0 == nil {
return false
}
for node := hd1; node != nil; node = node.Next {
if node.Data == intersectionValue {
break
}
before1 = node
}
if before1 == nil {
return false
}
before0.Next = before1.Next
return true
}