This question already has answers here:
Finding the intersecting node from two intersecting linked lists
(6 answers)
Closed 9 years ago.
MergePoint (LinkList list1, LinkList list2){
p = list1.head;
q = list2.head;
while (p.next!=null && q.next!=null){
if (p.next == q.next){
System.out.print(p.value + " is the Merging node");
return;
}
p=p.next;
q=q.next;
}
}
I'm trying to solve a problem to find out the merging node of 2 linked lists.
Before looking at other solutions, I decided to write my code and then compare to the other existing solutions.
The approach ive taken here is to find the common node that both the list pointers are pointing to.
Do you agree with this code or is there something im missing here?
Three solutions come to mind.
First, the nested loop Irfy posted. It uses constant memory but O(N*M) time, where N and M are the lengths of the two lists.
Second, you can trade space for time, by putting every node of one list into a HashSet first, then walking the other list and doing lookups into the HashSet. Because that lookup is O(1), the total time is O(N+M) (building the hashtable and walking the other list). However, the trade-off is O(N) space required for the table.
Third, if you're allowed to modify the data at least temporarily, you can make one of the lists circular (by connecting the next pointer of its last node to the first) and then use the algorithms described by Stepanov in Elements of Programming to solve the problem in O(N+M) time and O(1) space, because you know that one of the lists is now circular, whereas the other is P-shaped: it starts with its own part and eventually hits the circle of the other list. The place where it hits is called the connection point, and Stepanov gives you an algorithm to find it. Finally, you just unhook the last node again.
The algorithms in question are actually available in the sample chapter, which you can download here:
http://www.elementsofprogramming.com/book.html
Your code will only work for the special class of cases where the merging node is in the same position in both the lists. I don't think there's an easy, sub-O(n^2) way to do this -- in other words, you'll need to compare every node of one list, with every next of second list, and vice versa.
MergePoint (LinkList list1, LinkList list2) {
p = list1.head;
while (p != null) {
q = list2.head;
while (q != null) {
if (p == q){
System.out.print(p.value + " is the Merging node");
return;
}
q = q.next;
}
p = p.next;
}
}
This will only work if the "merging nodes" are at the same position in the list.
For example, let's say you have two linked lists...
List 1 has 5 nodes (nodes A, B, C, D, E)
List 2 has 6 nodes (nodes V, W, X, Y, C, D)
Obviously the common node is C. What you seem to be looking for in your code is the node that points to the common node (don't know if it really has a name, merging node is as good as anything,) so in this case you are looking for A and Y.
Your code will do something like this:
A.next == V.next? no
B.next == W.next? no
C.next == X.next? no
and so on and so forth. This is in the format [Element from List 1 compared with Element from List 2]
What you really want to do is compare the first element of List 1 with all the elements of List 2. Then, if you don't find it, compare the second element of List 1 with all the elements of list 2, and continue to do this so on and so forth.
Since this sounds like a homework question, I won't give you the answer (but I will give you a hint: you will probably need nested loops,) but if you have any further questions with implementing it, then ask away.
Also, may want to look at a special case for the head node, in case the first node in either list is the common node. In this case, you're only comparing the "next" node, meaning the very first one won't ever match if it is the common node between any of the two lists.
Related
Is it possible to convert a linked list to binary search tree BST.
and also have a link between them in a way of the current element, is pointing to the same in both linked list and BST
linked list :
3 , 5 ,6 ,1, 2 ,0,4
BST :
3
/ \
1 5
/ \ / \
0 2 4 6
when current of the binary search tree points to 1
it should also point to 1 in the linked list
Absolutely, you can use the same nodes in both data structures. The nodes would then each have the two links of their "linked-list-ness" and the two children of their "BST-ness".
So as a quick example, a node might have fields like this:
class Node {
public Node next, prev; // for the linked list
public Node left, right; // for the BST
// put some data in here too
}
It takes some care to use those nodes, because it's easy to get the two data structures "out of sync", for example if you remove a node from one but forget to remove it from the other. Then again, maybe that's what you want. But other things stay the same, for example if you do rotations in the BST then you don't have to touch the linked-lists fields at all, and similarly if you swap two nodes in the linked-list then the BST fields are not affected at all. So in those cases the code will be the same as it would have been if you had a normal kind of node that is part of only one data structure.
Of course this trick does not apply to the standard library implementations.
You can absolutely have that as harold pointed out above. And as he also points out, you can get them out of sync if your implementation has bugs that allow the data structures to go out of sync.
So, you could do this instead:
//YourBST.java
public class YourBST<T> {
public List<T> toList() { //Convert this to a list }
}
//YourList.java
public class YourList<T> {
public YourBST<T> toBST() { //... }
}
And then, when modifying one or the other..just call the conversion methods to set the other datastructure.
YourBST<String> bst = new YourBST<String>();
YourList<String> list = new YourList<String>();
modify(bst); //modify your BST in some way
list = bst.toList();
modify(list); //modify your List in some way
bst = list.toBST();
Edit: if you indeed want the same object to have prev/next references as well as left/right references, that still requires the node class as Harold described above. This solution simply fixes the "out of sync" problem.
This question already has answers here:
When to use LinkedList over ArrayList in Java?
(33 answers)
Closed 9 years ago.
Talking in Java's context. If I want to insert in the middle of either an ArrayList or a linkedList, I've been told that Arraylist will perform terribly.
I understand that it is because, we need to shift all the elements and then do the insertion. This should be of the order n/2 i.e. O(n).
But is not it the same for linkedList. For linked List, we need to traverse till the time we find the middle, and then do the pointer manipulation. In this case too, it will take O(n) time. Would not it?
Thanks
The reason here is that there's no actual shifting of elements in the linked list. A linked list is built up from nodes, each of which holds an element and a pointer to the next node. To insert an element into a list requires only a few things:
create a new node to hold the element;
set the next pointer of the previous node to the new node;
set the next pointer of the new node to the next element in the list.
If you've ever made a chain of paper clips, you can think of each paper clip as being the beginning of the chain of it and all the paper clips that come after it. To stick a new paper clip into the chain, you only need to disconnect the paper clips at the spot where the new one will go, and insert the new one. A LinkedList is like a paper clip chain.
An ArrayList is kind of like a pillbox or a mancala board where each compartment can hold only a single item. If you want to insert a new one in the middle (and keep all the elements in the same order), you're going to have to shift everything after that spot.
The insertion after a given node in a linked list is constant time, as long as you already have a reference to that node (with a ListIterator in Java), and getting to that position will typically require time linear in the position of the node. That is, to get to the _n_th node takes n steps. In an array list (or array, or any structure that's based on contiguous memory, really) the address of the _n_th element in the list is just (address of 1st element)+n×(size of element), a trivial bit of arithmetic, and our computing devices support quick access to arbitrary memory addresses.
I think, when analysing the complexity, you need to take into account the metric you are using. In the ArrayList, your metric is shuffling, which is just assignment. But this is quite a complex operation.
On the other hand, you're using a LinkedList, and you're simply looking going to the reference. In fact, you only perform 1 insertion. So while the algorithmic complexity will wind up similar, the actual processes that are being executed at O(n) time are different. In the case of an ArrayList, it is performing a lot of memory manipulation. In the case of a LinkedList, it's only reading.
For those saying he doesn't understand LinkedLists
A LinkedList only has a pointed at the start, and a pointer at the end. It does not automatically know the Node behind the node you want to delete (unless it's a doubly linked list) so you need to traverse through the list, from the start by creating a temp pointer, until you come to the node before the one you want to delete, and I believe it's this that OP is discussing.
I am thinking on the Algo to find the 3rd last element in the Singly Link List and I come up with one by myself(space in-efficient)
Put the Link List in a ArrayList using a loop with O(n)time complexity [a lot of space complexity]
then find the size of Arraylist and retrieve the element[required element] at (size-2) index location
Please guide me if my algo make sense
FYI
Other I searched is :
Put two pointers and keep 1st pointer on 1st element and 2nd pointer on 3rd element and move them parallel
When the second pointer reaches the end of LinkList, retrieve the node[required node] which is pointed by the 1st pointer
Use two pointers: pointer-1 and pointer-2
make pointer-1 points to third node in single linked list.
pointer-1 = node1->next->next; // point to 3rd nd
node1-->node2-->node3-->node4---> ...... -->node-last
^
|
pointer-1
Now set pointer-2 points to first-node
pointer-2 = node1; // point to 1st nd
node1-->node2-->node3-->node4---> ...... -->node-last
^ ^
| |
pointer-2 pointer-1
Now, travel in linked list in a loop till pointer-1 points to last node, in loop also update pointer-2 (every time to next node of itself )
while (pointer-1->next!=NULL){// points to last node
pointer-1 = pointer-1 -> next;
pointer-2 = pointer-2 -> next;
}
When loop ends pointer-1 points to last-node, pointer-2 points to third last
node1-->node2-->........ ->node-l3-->node-l2-->node-last
^ ^
| |
pointer-2 pointer-1
It works in O(n) times, where n is number of nodes in linked-list.
Since the linked list is singly linked, you need to traverse it from the beginning to end to know what the 3rd to last element is, os O(n) time is unavoidable (unless you maintain a pointer to the 3rd to last element in your linked list).
Your 2 pointers idea, will use constant space. This is probably the better option, since creating an ArrayList will have more overhead, and use more space.
Get two pointers. pA, pB
Move pA to 3 elements advance and pB to the head:
1->2->3->4-> .... ->99->100
| |
pB pA
After this, move both pointers in the same loop till pA reaches to the last element.
At that point pB will be pointing to the last 3rd element
1->2->3->4-> .... ->98->99->100
| |
pB pA
Edited:
traversal will be one:
while(pA->next!=null){
pA = pA->next;
pB = pB->next;
}
Here pB will be 3rd last
An alternative view to solve this even though it is O(n)
Create an empty array(n), start a pointer into this array at 0, and start from the beginning of the linked list as well. Every time you visit a node store it in the current index of the array and advance the array pointer. Keep filling the nodes in the array, and when you reach the end of the array please start from the beginning again so as to overwrite.
Now once you end the final end of the list the pointer nth elemtn from end :)
In practice, a Java LinkedList keeps track of its size, so you could just go to 'list.get(list.size()-2)', but with a constructed linked list, I'd do the following:
Keep an array of 3 values. As you traverse the list, add the update the value at array[i%3]. When there are no more values, return the value at array[(i-2)%3].
The first thing I'd do is ask you to reconsider your use of a singly linked list. Why not just store your data in an ArrayList? It does everything you seem to want, and it's a builtin so it's relatively efficient compared to what most people would write.
If you were bound and determined to use a linked list, I'd suggest keeping a direct pointer to the 3rd last element (tle). Insertions are easy - if they come before the tle, do nothing; if after, advance the tle pointer to the tle's next. Removals are more of a hassle, but probably not most of the time. If the removal occurs before the tle, it's still the tle. The annoying situation is if the element to be removed is the tle or later, in which case you get to iterate through from the beginning until the next() reference of the current node is the tle. The current node will become the new tle, and you can then proceed with the removal. Since there are only three nodes which invoke this level of work, you'll probably do all right most of the time if the list is sizable.
A final option, if removals from the end are a frequent occurrence, is to maintain your list from back to front. Then the tle becomes the third from the front for maintenance purposes.
//We take here two pointers pNode and qNode both initial points to head
//pNode traverse till end of list and the qNode will only traverse when difference
// between the count and position is grater than 0 and pthNode increments once
// in each loop
static ListNode nthNode(int pos){
ListNode pNode=head;
ListNode qNode=head;
int count =0;
while(qNode!=null){
count++;
if(count - pos > 0)
pNode=pNode.next;
qNode=qNode.next;
}
return pNode;
}
I'm having a really difficult time solving this problem. I have spent hours on it and can't figure it out.
I have a linked list that I am trying to manually sort. My nodes are called CNodes. There is a start CNode, a tail CNode and a newNext CNode.
Each Node contains a contact. The contact has a firstname that I am trying to sort the list by.
I know there are more automatic ways to do this, but I need to demonstrate that I understand how to sort (which clearly I do not at this point).
I am trying to do this by iterating over each node and comparing it to start, then changing the start entity if it qualifies.
This code is not working...I've been working on it for two days and am really stuck.
Any specific suggestions would be really appreciated.
CNode nextNode=start;
while(nextNode.getNext()!=null) {
CNode newNext;
tail=nextNode;
while(tail!=null) {
if(start.getContact().getStrFirstName().compareTo(tail.getContact().getStrFirstName()) > 0) {
//We put the starting node in a temp node
newNext=start;
newNext.setNext(tail.getNext());
//We set our current node to the start
start=tail;
start.setNext(newNext);
//Set the next node of start to the original next one of the one we
//just removed from the chain
//Set current marker to the new first nodes' next entity
tail=start.getNext();
//Set the next node for the marker to the one we just removed
} else {
tail=tail.getNext();
}
}
nextNode=nextNode.getNext();
}
The best thing you can do is start with an array, and get the sorting concept down. You also need to figure out what type of sort you are going to do, you're currently trying to do a bubble sort. There is also a merge sort, quick sort, and others. Once you pick the type of sort you want, you can then do it on an array, then move to node.
Here are some sorts:
https://github.com/BlaineOmega/MergeSort Bubble sort:
http://en.wikipedia.org/wiki/Bubble_sort Quick sort:
http://en.wikipedia.org/wiki/Quicksort
So what you're doing is a bubble sort. For a visual representation of what the is, look at this (from Wikipedia): http://upload.wikimedia.org/wikipedia/commons/c/c8/Bubble-sort-example-300px.gif
So in the while loop, when two nodes need to be switched, we're going to store the 'next' (current) node into a temp, put the tail in the next node, and put the temp into the tail, like a triangle.
temp
/ ^
/ \
V \
tail -- next
I attempted to rewrite your code, but was confused as to if start is you're root node, and if not, what is you're root node. If it is, it should be only used once, and that is declaring you're tail node.
Good luck, hope I helped,
Stefano
I am trying to create a complete binary tree using a linked list, instead of arraylist, without comparing node values.
What I mean is on inserting a new value, I do not wish to compare if the value is less, greater or equal than the root's value, so as to add it either to the left link or to the right link, but still be able to create a complete binary tree.
Do you think it's possible? If yes, do you have any idea or can you point me to something I can use/read to do it?
EDIT:
Here's an example to make my question more clear:
I am adding the numbers in the order presented through the insert method: 1 2 3 4 5 6
the insert method takes care of the structure of the tree.
1 becomes the root since it's the first value added.
2 is the left child of 1
3 the right child of 1
4 the left child of 2
5 the right child of 2
6 the left child of 3
SOLUTION:
public void insert(Comparable item) {
total++;
if (root == null) {
root = new TreeNode(item);
} else {
int quotient=total;
Stack path = new Stack();
TreeNode p = root; // helper node to follow path
quotient /= 2; // skip last step
while (quotient>1) { // build path to follow
path.push(quotient%2);
quotient /= 2;
}
while (!path.isEmpty()) {
Object q = path.pop();
if (q.equals(0))
p = p.getLeft();
else
p = p.getRight();
}
if (total%2==0) // check last step
p.setLeft(new TreeNode(item));
else
p.setRight(new TreeNode(item));
}
}
Keep a count of how many items you have in the tree.
Then, to add the nth item follow the path created by dividing n repeatedly by two and keeping track of the remainder. Follow the "route" created by the remainder in reverse: where 1 means right and 0 means left.
For example, to add the 11th item:
11/2 = 5 (1)
5/2 = 2 (1)
2/2 = 1 (0)
That means from the root, you'd go left, right, right.
It seems your question is unrelated to LinkedList. It was a little confusing.
If you know how many elements are in tree already, you can calculate the position from that number. It's binary representation is the path you have to take. See here.
If you don't know anything about current state of the tree, you need to do a Breadth-first search to find the first empty spot.
The entire basis of a binary tree is on comparing values and sending them left or right down the tree.
Therefore, it is impossible to create a binary tree without comparisons.
But you did say upon insertion, so you could add the item to the end of the list, and then sort it when you call for the tree. Like this:
list.add(value); //Just add the item to the end
call(); //This method would sort the list into a tree appropriately.
This option also allows you to change the type of tree dynamically, since you could add a parameter to call() that specifies a tree type.