From 047db8d544e5c68b049ae063f4c0d8d0d029a613 Mon Sep 17 00:00:00 2001 From: anebz Date: Mon, 29 Jul 2019 08:12:01 +0200 Subject: [PATCH] 2.2. return kth to last --- 02. Linked lists/2.1. remove_duplicates.md | 8 +- 02. Linked lists/2.2. return_kth_to_last.md | 117 ++++++++++++++++++++ 2 files changed, 121 insertions(+), 4 deletions(-) create mode 100644 02. Linked lists/2.2. return_kth_to_last.md diff --git a/02. Linked lists/2.1. remove_duplicates.md b/02. Linked lists/2.1. remove_duplicates.md index 4af5975..334788d 100644 --- a/02. Linked lists/2.1. remove_duplicates.md +++ b/02. Linked lists/2.1. remove_duplicates.md @@ -14,14 +14,14 @@ class Node { int data; public Node(int d){ - data = d, + data = d; } void appendToTail(int d){ Node end = new Node(d); Node n = this; while (n.next != null){ - n = n.next + n = n.next; } n.next = end; } @@ -29,8 +29,8 @@ class Node { Node a = new Node(3); Node b = new Node(2); -Node d = new Node(1); -Node c = new Node(3); +Node c = new Node(1); +Node d = new Node(3); a.appendTotail(b); b.appendToTail(c); c.appendToTail(d); diff --git a/02. Linked lists/2.2. return_kth_to_last.md b/02. Linked lists/2.2. return_kth_to_last.md new file mode 100644 index 0000000..84a623c --- /dev/null +++ b/02. Linked lists/2.2. return_kth_to_last.md @@ -0,0 +1,117 @@ +# 2.2. Return kth to last + +## Find the kth to last element of a singly linked list + +Linked list: + +```java +class Node { + Node next = null; + int data; + + public Node(int d){ + data = d; + } + + void appendToTail(int d){ + Node end = new Node(d); + Node n = this; + while (n.next != null){ + n = n.next; + } + n.next = end; + } +} + +Node a = new Node(3); +Node b = new Node(2); +Node c = new Node(1); +Node d = new Node(4); +a.appendTotail(b); +b.appendToTail(c); +c.appendToTail(d); +``` + +## 2.2.1. First idea + +Iterate through the list until we find n.data == my_number. Then create a new node with this node as head, and append all next nodes to it. + +```java +void return_kth(Node a, int my_number){ + Node new_head = null; + while(a != null){ + if(new_head != null){ + new_head.appendToTail(a); + } + else if(a.data == my_number){ + new_head = a; + } + a = a.next; + } +} +``` + +Iterates through the list with `a = a.next;`, until either reaching the end where `my_number` isn't found or until finding it. If it finds it, initialize `new_head`, and add all nodes from this point on. + +## 2.2.2. Hint 1 + +> What if you knew the size of the linked list, what's the difference between finding the kth-to-last element and finding the Xth element? + +Both are O(n) since we have to iterate the list anyway. If we're looking for the Xth element and find it, we just stop there. If we're looking for the kth-to-last, we iterate the whole list anyway. + +## 2.2.3. Hint 2 + +> If you don't know the size, can you compute it? How does it impact the runtime? + +I can iterate the whole list, it takes O(n). The algorithm is still O(n). + +## 2.2.4. Hint 3 + +> Do it recursively, if I can find the (k-1)th-to-last element, can you find the kth element? + +Am I missing something here, why is this recursive? + +## 2.2.5. Hint 4 + +> Maybe return multiple values, some languages don't directly support this but there are workarounds, find them + +Maybe I don't need to return the linked list of kth-to-last, but just the numbers. Still, it's not recursive. Just a while loop. + +```java +void return_kth(Node a, int my_number){ + kth = new ArrayList(); + Node new_head = null; + while(a != null){ + if(new_head != null){ + kth.add(a.data); + } + else if(a.data == my_number){ + new_head = a; + kth.add(a.data); + } + a = a.next; + } +} +``` + +Just add all elements to an ArrayList? + +## 2.2.6. Hint 5 + +> Can you do it iteratively? If you have two pointers looking to adjacent nodes and they were moving at the same speed through the linked list. When one hits the end of the linked list, where will the other be? + +When the forward one hits the end of the linked list, the other will be just behind it. Don't understand the question. + +## 2.2.7. Solution + +> We have defined `k` such as passing k=1 returns the last element, k=2 return to the second last element, and so on. + +Of course, to know the kth- last element you need to know the size of the list. The question was a bit confusing. + +> Option 1 + +Find out size of list, then get the kth element. O(n) + +> Option 2 + +From the hints, have 2 pointers, with a distance of `k`. When the forward one reaches the end, the latter one will be on the kth-to-last element. Return this element.