// Finds the first node of the loop func FindCorruptNode(l ds.LinkedList) *ds.Node { head := l.Head() slowRunner := head fastRunner := head.Next() corruptNode := &ds.Node{} // Find the Collusion for { // There is no loop if slowRunner.Next() == nil || fastRunner.Next() == nil { return nil } // Move slow runner one point slowRunner = slowRunner.Next() // Move fast runner two points fastRunner = fastRunner.Next().Next() // Are they matched ? if slowRunner == fastRunner { fastRunner = fastRunner.Next() break } } // Find the collision point slowRunner = head for { if slowRunner == fastRunner { corruptNode = slowRunner break } // Move one point ahead for two of runners slowRunner = slowRunner.Next() fastRunner = fastRunner.Next() } return corruptNode }
func initializeLoopedList() []findCorruptNodeTestPair { l1 := ds.LinkedList{} l2 := ds.LinkedList{} node := &ds.Node{} // Create a looped linked list // 0->1->2->3->4->5->6->3->4->5->6->3->4->5->6... for i := 0; i < 6; i++ { n := ds.Node{} n.SetValue(i) l1.Add(&n) if i == 5 { temp := l1.Head().Next().Next().Next() node = temp l1.Add(temp) } } // Create a non-looped linked list for i := 0; i < 10; i++ { n := ds.Node{} n.SetValue(i) l2.Add(&n) } // we can expand test cases var loopTests = []findCorruptNodeTestPair{ {l1, node}, {l2, nil}, // no loop } return loopTests }
// Gives sliced linked list from kth element to last element. // Also it assumes that, we don't know size&last element of the linkedlist. func Slice(l datastructures.LinkedList, kth int) *datastructures.LinkedList { if kth <= 0 { return nil } current := l.Head() runner := current sliced_list := datastructures.LinkedList{} count := 0 for current != nil { runner = current if count == kth { sliced_list.SetHead(current) for runner != nil { runner = runner.Next() } break sliced_list.SetTail(current) } count++ current = current.Next() } if sliced_list.Head() != nil { return &sliced_list } else { return nil } }
// Removes duplicate nodes inside the given linkedlist func RemoveDuplicates(l *datastructures.LinkedList) { current := l.Head() for current != nil { runner := current for runner.Next() != nil { if runner.Next().GetValue() == current.GetValue() { runner.SetNext(runner.Next().Next()) } else { runner = runner.Next() } } current = current.Next() } }
// checks wheter given list is palindrome func IsPalindrome(l ds.LinkedList) bool { head := l.Head() // reverse given list reversed_list := reverseList(l) reversed_head := reversed_list.Head() // checks items until half of the list for i := 0; i < l.Len()/2; i++ { if head.GetValue() != reversed_head.GetValue() { return false } head = head.Next() reversed_head = reversed_head.Next() } return true }
// partition given list into two parts due to the given value // and then merge them together. func PartitionList(l datastructures.LinkedList, value int) datastructures.LinkedList { beforeValue := datastructures.LinkedList{} afterValue := datastructures.LinkedList{} head := l.Head() for head != nil { n := datastructures.Node{} n.SetValue(head.GetValue()) if head.GetValue() < value { beforeValue.Add(&n) } else { afterValue.Add(&n) } head = head.Next() } beforeValue.SetTail(afterValue.Head()) return beforeValue }
// Sum up two linked list in forward order // Input:(6 -> 1 -> 7) + (2 -> 9 -> 5).Thatis,617 + 295. // Output: 9 -> 1 -> 2.That is, 912. // we assume that, result integer does not exceed integer size func SumLinkedListForward(l1 ds.LinkedList, l2 ds.LinkedList) int { head1 := l1.Head() head2 := l2.Head() num1 := 0 num2 := 0 multiplier1 := exp(10, l1.Len()-1) multiplier2 := exp(10, l2.Len()-1) // convert l1 list to int for head1 != nil { num1 += multiplier1 * head1.GetValue() multiplier1 = multiplier1 / 10 head1 = head1.Next() } // convert l2 list to int for head2 != nil { num2 += multiplier2 * head2.GetValue() multiplier2 = multiplier2 / 10 head2 = head2.Next() } return num1 + num2 }
// Sum up two linked list in reverse order // Input:(7-> 1 -> 6) + (5 -> 9 -> 2).Thatis,617 + 295. // Output: 2 -> 1 -> 9.That is, 912. // we assume that, result integer does not exceed integer size func SumLinkedListReverse(l1 ds.LinkedList, l2 ds.LinkedList) int { head1 := l1.Head() head2 := l2.Head() num1 := 0 num2 := 0 multiplier := 1 // convert l1 list to int for head1 != nil { num1 += multiplier * head1.GetValue() multiplier = multiplier * 10 head1 = head1.Next() } multiplier = 1 // convert l2 list to int for head2 != nil { num2 += multiplier * head2.GetValue() multiplier = multiplier * 10 head2 = head2.Next() } return num1 + num2 }