예제 #1
0
파일: 2.6.go 프로젝트: muraty/ctci
// 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
}
예제 #2
0
파일: 2.6_test.go 프로젝트: muraty/ctci
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
}
예제 #3
0
파일: 2.2.go 프로젝트: muraty/ctci
// 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
	}
}
예제 #4
0
파일: 2.5_test.go 프로젝트: muraty/ctci
func initializeReverseList() []sumLinkedListReverseTestPair {
	l1 := datastructures.LinkedList{}
	l2 := datastructures.LinkedList{}
	// l2 : 1->2->3    = 321
	// l1 : 1->2->3->4 = 4321
	// summed value    = 4642
	value := 4642

	// Create l1 : 1->2->3->4 = 4321
	for i := 1; i < 5; i++ {
		n := datastructures.Node{}
		n.SetValue(i)
		if i == 4 {
			l1.Add(&n)
			continue
		}
		l1.Add(&n)
	}
	// Create l2 : 1->2->3    = 321
	for i := 1; i < 4; i++ {
		n := datastructures.Node{}
		n.SetValue(i)
		l2.Add(&n)
	}
	// we can expand test cases
	var reverseTests = []sumLinkedListReverseTestPair{
		{l1, l2, value},
	}
	return reverseTests
}
예제 #5
0
파일: 2.7_test.go 프로젝트: muraty/ctci
func initializePalindromeTests() []palindromeTestPair {
	l1 := ds.LinkedList{} // palindrome
	l2 := ds.LinkedList{} // non-palindrome

	// create a palindrome list
	// move until half of the list to create a palindrome list
	for i := 0; i < 5; i++ {
		n := ds.Node{}
		n.SetValue(i)
		l1.Add(&n)
	}
	// move from half of the list to create a palindrome list
	for i := 5; i >= 0; i-- {
		n := ds.Node{}
		n.SetValue(i)
		l1.Add(&n)
	}

	// create a non-palindrome list
	for i := 0; i < 10; i++ {
		n := ds.Node{}
		n.SetValue(i)
		l2.Add(&n)
	}
	// we can expand test cases
	var palindromeTests = []palindromeTestPair{
		{l1, true},
		{l2, false},
	}
	return palindromeTests
}
예제 #6
0
파일: 2.1.go 프로젝트: muraty/ctci
// 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()
	}
}
예제 #7
0
파일: 2.7.go 프로젝트: muraty/ctci
// 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
}
예제 #8
0
파일: 2.7.go 프로젝트: muraty/ctci
// reverse given list
func reverseList(l ds.LinkedList) ds.LinkedList {
	temp := l.Copy()
	reversed_list := ds.LinkedList{}
	head := temp.Head()
	current_node := head
	var prev_node *ds.Node
	for {
		if current_node != nil {
			next_node := current_node.Next()
			current_node.SetNext(prev_node)
			prev_node = current_node
			current_node = next_node
		} else {
			reversed_list.SetHead(prev_node)
			break
		}
	}
	return reversed_list
}
예제 #9
0
파일: 2.5_test.go 프로젝트: muraty/ctci
func initializeForwardList() []sumLinkedListForwardTestPair {
	l1 := datastructures.LinkedList{}
	l2 := datastructures.LinkedList{}
	// l1 : 1->2->3->4 = 1234
	// l2 : 1->2->3    = 123
	// summed value    = 1357
	value := 1357

	// Create l1 : 1->2->3->4 = 1234
	for i := 1; i < 5; i++ {
		n := datastructures.Node{}
		n.SetValue(i)

		l1.Add(&n)
	}
	// Create l2 : 1->2->3    = 123
	for i := 1; i < 4; i++ {
		n := datastructures.Node{}
		n.SetValue(i)
		l2.Add(&n)
	}

	// we can expand test cases
	var forwardTests = []sumLinkedListForwardTestPair{
		{l1, l2, value},
	}
	return forwardTests
}
예제 #10
0
파일: 2.3_test.go 프로젝트: muraty/ctci
func TestDeleteNode(t *testing.T) {
	deleteNodeTests := initializeDeleteNode()
	for _, test := range deleteNodeTests {
		// save original list in a temporary list
		temp := datastructures.LinkedList{}
		for elem := range test.orig.GetElements() {
			n := datastructures.Node{}
			n.SetValue(elem)
			temp.Add(&n)
		}

		DeleteNode(&test.node)
		// item by item check through two lists
		for i := 0; i < test.orig.Len(); i++ {
			if test.orig.Find(i) != test.result.Find(i) {
				t.Error("For ", temp.GetElements(),
					"Expected", test.result.GetElements(),
					"got", test.orig.GetElements())
			}
		}
	}
}
예제 #11
0
파일: 2.5.go 프로젝트: muraty/ctci
// 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
}
예제 #12
0
파일: 2.5.go 프로젝트: muraty/ctci
// 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
}
예제 #13
0
파일: 2.2_test.go 프로젝트: muraty/ctci
func initializeSlice() []sliceTestPair {
	orig := datastructures.LinkedList{}
	for i := 0; i < 10; i++ {
		n := &datastructures.Node{}
		n.SetValue(i)
		orig.Add(n)
	}

	target := datastructures.LinkedList{}
	for i := 3; i < 10; i++ {
		n := &datastructures.Node{}
		n.SetValue(i)
		target.Add(n)
	}
	var sliceTests = []sliceTestPair{
		{orig, &target, 3},
		{orig, nil, 30},
		{orig, nil, -3},
	}
	return sliceTests
}
예제 #14
0
파일: 2.4_test.go 프로젝트: muraty/ctci
func initializePartitionList() []partitionListTestPair {
	orig := datastructures.LinkedList{}
	result := datastructures.LinkedList{}
	value := 4
	for i := 0; i < 10; i++ {
		n := datastructures.Node{}
		n.SetValue(i)

		// Set before values
		if i < value {
			orig.Add(&n)
			// Set after values
		} else {
			result.Add(&n)
		}
	}
	// we can expand test cases
	var partitionListTests = []partitionListTestPair{
		{orig, result, value},
	}
	return partitionListTests
}
예제 #15
0
파일: 2.3_test.go 프로젝트: muraty/ctci
func initializeDeleteNode() []deleteNodeTestPair {
	node := datastructures.Node{}
	orig := datastructures.LinkedList{}
	target := datastructures.LinkedList{}
	for i := 0; i < 10; i++ {
		n := datastructures.Node{}
		n.SetValue(i)
		orig.Add(&n)

		// will delete this node
		// so, don't add this node to result list
		if i == 4 {
			node = n
		} else {
			target.Add(&n)
		}
	}
	// we can expand test cases
	var deleteNodeTests = []deleteNodeTestPair{
		{orig, target, node},
	}
	return deleteNodeTests
}
예제 #16
0
func TestRemoveDuplicates(t *testing.T) {
	l := datastructures.LinkedList{}
	for i := 0; i <= 10; i++ {
		n := &datastructures.Node{}
		n.SetValue(i % 3)
		l.Add(n)
	}

	RemoveDuplicates(&l)

	if l.Len() != 3 {
		t.Error("Wrong length, Len() must be", 3)
	}
	if l.Find(0) == nil || l.Find(1) == nil || l.Find(2) == nil {
		t.Error("Wrong deletion for one of the elements.")
	}
}
예제 #17
0
파일: 2.4.go 프로젝트: muraty/ctci
// 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
}