Runner technique to combine two equal Linked Lists - algorithm

So, I am facing a doubt here.
I was reading the book Cracking the coding Interview. The following text is written over there.
Suppose you had a linked list a1->a2....->an->b1->b2....bn, and you want to rearrange it into a1->b1->a2->b2->.....an->bn. You don't know the length of the linked list but all you know is that it is an even number.
(Here both the linked lists are of same length)
You could have one pointer p1 (fast pointer) move every two elements for every one move that p2 makes. When p1 hits the end of the linked list, p2 will be at the endpoint. Then, move p1 back to the front and begin "weaving" the elements. On each iteration, p2 selects an element and inserts it after p1.
I don't understand how when p1 hits the end of the linked list, p2 will be at the midpoint. This is how I am imagining it if n=3 (length = 6). Each step below represents an iteration.
1. a1 (p1, p2)->a2->a3->b1->b2->b3
2. a1->a2 (p2)->a3 (p1)->b1->b2->b3
3. a1->a2->a3 (p2)->b1->b2 (p1)->b3
4. Index out of bounds error because p2 now points to a node after b3.
Am I going somewhere wrong?

Let n = 2. We are starting with a list:
a1 -> a2 -> b1 -> b2
Let p1 be a "fast" pointer initially pointing to the successor of head.
Let p2 be a "slow" pointer initially pointing to the head.
p1
a1 -> a2 -> b1 -> b2
p2
We move p1 by two and p2 by one until p1 reaches the end of the list (there is no next).
p1
a1 -> a2 -> b1 -> b2
p2
Move p1 back to the head.
p1
a1 -> a2 -> b1 -> b2
p2
Advance p2.
p1
a1 -> a2 -> b1 -> b2
p2
"Weaving" starts.
Take element pointed by p2 and move it after p1. Advance p1 after inserted element.
p1
a1 -> b1 -> a2 -> b2
p2
Take element pointed by p2 and move it after p1. Advance p1 after inserted element.
p1
a1 -> b1 -> a2 -> b2
p2
p1 is null, terminate.

Start p2 at second position.
a1(p1)-> a2 (p2) -> a3 -> a4 -> b1 -> b2 -> b3 -> b4
a1-> a2 (p1) -> a3 -> a4 (p2)-> b1 -> b2 -> b3 -> b4
a1-> a2 -> a3(p1) -> a4 -> b1 -> b2(p2) -> b3 -> b4
a1-> a2 -> a3 -> a4(p1) -> b1 -> b2 -> b3 -> b4(p2)

You can simply implement by using Java:
public static void findMidElOfLinkedList(FindMidElementOfLinkedList findMidElementOfLinkedList) {
Node node = findMidElementOfLinkedList.head;
Node slow = node;
Node fast = node;
while (fast != null && fast.next != null) {
fast = fast.next.next; // increase 2
slow = slow.next; // increate 1
}
System.out.println(slow.data);
/*
* Slow runner goes at a pace of 1 element per move, fast runner goes 2 elements per move.
When the fast runner reaches the end of the linked list, then slow runner is sitting at the middle. Testing this out for one/two middle cases work.
Time O(N), faster than the previous brute force method, Space: O(1).
* */
}

Related

How to use edge as constraint when drawing graph but not when computing rank

I have a dot graph, and I am using the constraint=false because for some of the edges, I don't want the edge to affect the rank of the nodes. Unfortunately, it appears that this means that the dot engine doesn't use that edge for layout of nodes within a rank, and it also seems to do a worse job at routing the edge itself. For example, see this graph:
digraph G {
subgraph G1 {
a1 -> b1
d1 -> b1
b1 -> c1
a1 -> c1 [constraint=false]
}
subgraph G2 {
a2 -> b2
d2 -> b2
b2 -> c2
a2 -> c2
}
}
see online
the a1 -> c1 edge could be routed left of the b1 node, but isn't. I don't want a1 -> c1 to be used for computing rank.
Is there a way to get the "best of both worlds" here? I.e. a way to get the better layout (like the a2 -> c2 edge) but not use the edge for computing rank?
I don't know a way to not use a edge for ranking, but use it for the layout (without affecting the ranking). Edges with constraint=false seem to be laid out after the placement of the nodes is determined.
What's left are some "hacks", not sure whether they are applicable in a generic manner for all of your use cases.
For example, if you make sure that the nodes linked with such an edge are mentioned before the others, the resulting layout is - at least in this example - improved:
subgraph G1 {
d1, a1;
a1 -> b1
d1 -> b1
b1 -> c1
a1 -> c1 [constraint=false]
}
example

fdp/graphviz: vertical misalignment at the beginning of rows even with forced positions

I'm exploring using fdp to do grid (rows, and columns) based diagram using fdp with forced positions. But to my surprise, the forced positions sometimes are still just suggestion, not really enforced. I wonder how I can have the positions completely enforced with graphviz, some layout engine, and some parameter combination?
Here are the illustration of my findings:
(I'm using emacs/org-mode/graphviz code block to generate the diagrams)
Case 1: single column, perfect alignment:
#+begin_src dot :file ./column1.png :cmdline -Kfdp -Tpng
graph dfd {
node[shape=box]
"(0.0, 0.0)" [pos="0.0, 0.0!"]
"(0.0, 0.1)" [pos="0.0, 0.1!"]
"(0.0, 0.2)" [pos="0.0, 0.2!"]
"(0.0, 0.3)" [pos="0.0, 0.3!"]
}
#+end_src
Resulting:
Case 2: 2 columns: even the first column is no longer aligned
#+begin_src dot :file ./column2.png :cmdline -Kfdp -Tpng
graph dfd {
node[shape=box]
"(0.0, 0.0)" [pos="0.0, 0.0!"]; "(0.1, 0.0)" [pos="0.1, 0.0!"]
"(0.0, 0.1)" [pos="0.0, 0.1!"]; "(0.1, 0.1)" [pos="0.1, 0.1!"]
"(0.0, 0.2)" [pos="0.0, 0.2!"]; "(0.1, 0.2)" [pos="0.1, 0.2!"]
"(0.0, 0.3)" [pos="0.0, 0.3!"]; "(0.1, 0.3)" [pos="0.1, 0.3!"]
}
#+end_src
resulting:
I also found that the more columns, the worse misalignment is. I found that fdp's layout algorithm is somehow elastic to avoid overlapping but I still don't understand for the first column, there should not be any overlapping yet.
Well, I'm not sure whether graphviz is really the tool of choice for what you want to achieve. But since I don't know, here some bits to get you going:
dot arranges the nodes you define in a hierarchical fashion that depends upon the order they are defined, upon the direction of the edges and upon a specific instruction rank = same for nodes that are on the same hierarchical level. dot automatically sets the width and height of the nodes according to the label, so if your labels have different length, you need to take that into consideration.
A very basic sample:
digraph so
{
// default/initial node style
node[ shape = box, width = 2, height = 1.5 ];
// default/initial edge style
edge[ style = invis ];
{rank = same; a1 -> a2 -> a3 -> a4 }
{rank = same; b1 -> b2 -> b3 -> b4 }
{rank = same; c1 -> c2 -> c3 -> c4 }
{rank = same; d1 -> d2 -> d3 -> d4 }
a1 -> b1 -> c1 -> d1;
a1[ label = "bla" ];
c1[ label = "long label\nwith new line" ];
}
which gives you
In this simple example, the rank = same instruction is not really necessary, you would achieve the same with
a1 -> b1 -> c1 -> d1;
a2 -> b2 -> c2 -> d2;
a3 -> b3 -> c3 -> d3;
a4 -> b4 -> c4 -> d4;
but the more elaborate your structure gets, the more the explicit ranking will help.

Data structure traversal

Lets say I have package A version 1 and package A version 2, Will call them A1 and A2 respectively.
If I have a pool of packages: A1, A2, B1, B2, C1, C2, D1, D2
A1 depends on B1, will represent as (A1, (B1)).
Plus A1 depends on any version of package C "C1 or C2 satisfy A1", will represent as (A1, (C1, C2))
combining A1 deps together, then A1 data-structure becomes: (A1, (B1), (C1, C2))
Also B1 depends on D1: (B1, (D1))
A1 structure becomes: (A1, ((B1, (D1))), (C1, C2))
similarly A2 structure is (A2, ((B2, (D2))), (C1, C2))
My question is: How can I select best candidate of package A, where I can select based on a condition (for example, the condition is the package does not conflict with current installed packages).
by combining A1 and A2: ((A1, ((B1, (D1))), (C1, C2)), (A2, ((B2, (D2))), (C1, C2)))
How can I traverse this data structure
So start with A1, if doesn't conflict check B1, if doesn't conflict check D1, if doesn't conflict check (C1, C2), and take one only either C1 or C2.
With this I end up selecting (A1, B1, D1, C1).
In case if A1 or any of its deps did not meet the condition, (for example if B1 conflicts with installed packages), then drop A1 entirely and move to check A2. then end up with (A2, B2, D2, C1).
What kind of traversal would that be?
I have been reading about in-order, pre-order, post-order traversal, and wondering if I need to do something similar here.
Assuming you are asking traversal on a more generic problem rather than working on this instance, I don't think there exists such a traversal.
Note that in-order is only applicable to BINARY trees. Any other kind of tree does not have in-order traversal. If your generic problem has B1, B2, B3, then apparently there wouldn't be a binary tree representation.
One property about traversal, is that the tree has all the information inclusively in the itself. When you traverse over a tree you never worry about "external information". In your case, your tree is not complete in information - you need to depend on external information to see if there is a conflict. e.g. B1 is installed - this information is never in the tree.
You can use adjacency list to represent the data:
Suppose the packages are A1, A2, B1, B2, C1, C2.
And A1 depends on B1 and C2, A2 depends on B1 and C1 and C2.
The above data can be represented as
[A1] -> [B1, C2]
[A2] -> [B1, C1, C2]
Use Topological Sorting to get the order of dependencies

Efficiently find lowest sum paths

This is a big ask but I'm a bit stuck!
I am wondering if there is a name for this problem, or a similar one.
I am probably over complicating finding the solution but I can't think of a way without a full brute force exhaustive search (my current implementation). This is not acceptable for the application involved.
I am wondering if there are any ways of simplifying this problem, or implementation strategies I could employ (language/tool choice is open).
Here is a quick description of the problem:
Given n sequences of length k:
a = [0, 1, 1] == [a1, a2, a3]
b = [1, 0, 2] == [b1, b2, b3]
c = [0, 0, 2] == [c1, c2, c3]
find paths of length k through the sequences as so (i'll give examples starting at a1, but hopefully you get the idea the same paths need to be derived from b1, c1)
a1 -> a2 -> a3
a1 -> b1 -> b2
a1 -> b1 -> a2
a1 -> b1 -> c1
a1 -> c1 -> c2
a1 -> c1 -> a2
a1 -> c1 -> b1
I want to know, which path(s) are going to have the lowest sum:
a1 -> a2 -> a3 == 2
a1 -> b1 -> b2 == 1
a1 -> b1 -> a2 == 2
a1 -> b1 -> c1 == 1
a1 -> c1 -> c2 == 0
a1 -> c1 -> a2 == 1
a1 -> c1 -> b1 == 1
So in this case, out of the sample a1 -> c1 -> c2 is the lowest.
EDIT:
Sorry, just to clear up the rules for deriving the path.
For example you can move from node a1 to b2 if you haven't already exhausted b2, and have exhausted the previous node in that sequence (b1).
An alternative solution using Dynamic Programming
Let's assume the arrays are given as a matrix A such that each row is identical to one of the original arrays. Your matrix will be of size (n+1)x(k+1), and make sure that A[_][0] = 0
Now, use DP to solve it:
f(x,y,z) = min { f(i,y,z-1) | x < i <= n} [union] { f(i+1,0,z) } + A[x][y]
f(_,_,0) = 0
f(n,k,z) = infinity for each z > 0
Idea: In each step you can choose to go to each of the following lines (same column) - or go to the next column, while decreasing the number of more nodes needed.
Moving to the next column is done via the dummy index A[_][0], without decreasing number of nodes needed to go more and without cost, since A[_][0] = 0.
Complexity:
This solution is basically a brute force, but using memorization of each already explored value of f(_,_,_) you basically need only to fill a matrix of size O(n*k^2), where each cell takes O(n) time to compute on first look- but in practice can be computed iteratively in O(1) per step, because you only need to minimize with the new element in the row1. This gives you O(n*k^2) - better than brute force.
(1) This is done by min{x1,x2,x3,...,xk} = min{x_k, min{x1,...,k_k-1}}, and we already know min{x1,...,k_k-1}
You can implement a modified version of A* algorithm.
Copy the matrix and fill it will 0s
foreach secondary diagonal m from the last to first
Foreach cell n in m
4. New matrix's cell n = old matrix cell n minus min(cell bellow n in new matrix, cell to the right of n in the new matrix).
Cell 0,0 in the new matrix is the shortest path
**implement A algorithem over the pseudocode above.

complicated graphviz tree structure

I am trying to create a tree structure with graphviz. I am open to either writing the graphviz code by hand or using the ruby-graphviz gem for ruby. Given the below picture can anyone provide any insight on the necessary code? Ignore that the lines are not straight...they should be when graphviz builds the graph. I am open to having dots/points when lines intersect as well.
I have played with ruby-graphviz and the family tree class...this is getting me part of the way there but I really need all lines to be straight and intersect at right angles and the out-of-the-box code doesn't seem to do that.
The code should be generic enough to allow for the "C" box to have children as well and for there also to be more children under "A".
The colors are irrelevant...the examples can exclude any coloring.
http://docs.google.com/drawings/pub?id=1lUTfgKP_LN0x7C3ItbsFjfLBuDTL84AtmoaW7YFn32Y&w=1036&h=713
A little late, I know, but I just wanted to show an other version without having to figure out the exact positions of each node.
digraph {
splines=false;
ranksep=0.05;
node[shape=box, color=lightblue, style=filled];
A;B;C;D;E;
node[shape=none, color=none, style=solid];
i1[label="Item 1"];
i2[label="Item 2"];
i3[label="Item 3"];
node[label="", width=0, height=0];
edge[arrowhead=none, color=blue];
{rank=same; n2; n1; n3;}
n2; n1; n3;
A -> n1;
n2 -> n1 -> n3;
{rank=same; B; C;}
n2 -> B;
n3 -> C;
{rank=same; n4; D;}
B -> n4 -> D;
{rank=same; n6; n5; i1;}
D -> n5 -> i1;
n4 -> n6;
{rank=same; n7; E;}
n6 -> n7 -> E;
{rank=same; n8; i2;}
E -> n8 -> i2;
{rank=same; n9; i3;}
i2 -> n9 -> i3;
}
Straight lines are enforced by:
splines=false - say no to splines
invisible nodes (nodes n1, n2,... n9)
placing nodes on the same rank with rank=same
It's still some work to get the dot file right, but it beats imho calculating yourself the position of each node.
Output looks like this:
As long as C has no child nodes, you'd have to apply some more trickery (invisible nodes) to display it all the way to the right.
In order to get a more general solution for different graphs, some further adaptations will probably be needed (apply weight to vertical edges, or group nodes which have to be vertically aligned, or use subgraphs, ...).
As far as I know this requires a little work-around; I will only do it in Graphviz DOT language. I give you the solution first, then provide some explanations of how you can extend it.
This is the resulting figure:
This is the Graphviz code producing the figure:
graph atree {
Item1 [shape=none,label="Item 1",pos="2.2,1.1!"];
Item2 [shape=none,label="Item 2",pos="2.2,0.1!"];
Item3 [shape=none,label="Item 3",pos="2.9,-0.3!"];
A [shape=box,color=lightblue,style=filled,pos="2,3!"];
B [shape=box,color=lightblue,style=filled,pos="1,2.1!"];
C [shape=box,color=lightblue,style=filled,pos="3,2.1!"];
D [shape=box,color=lightblue,style=filled,pos="1.5,1.5!"];
E [shape=box,color=lightblue,style=filled,pos="1.5,0.5!"];
D0 [style=invisible,fixedsize=true,width=0,height=0,pos="2,2.5!",label=""];
D1 [style=invisible,fixedsize=true,width=0,height=0,pos="1,2.5!",label=""];
D2 [style=invisible,fixedsize=true,width=0,height=0,pos="3,2.5!",label=""];
D3 [style=invisible,fixedsize=true,width=0,height=0,pos="1,1.5!",label=""];
D4 [style=invisible,fixedsize=true,width=0,height=0,pos="1,0.5!",label=""];
D5 [style=invisible,fixedsize=true,width=0,height=0,pos="1.5,1.1!",label=""];
D6 [style=invisible,fixedsize=true,width=0,height=0,pos="1.5,0.1!",label=""];
D7 [style=invisible,fixedsize=true,width=0,height=0,pos="2.2,-0.3!",label=""];
A -- D0 -- D1 -- B -- D3 -- D4 -- E [color=blue];
E -- D6 -- Item2 -- D7 -- Item3 [color=blue];
D0 -- D2 -- C [color=blue];
D3 -- D -- D5 -- Item1 [color=blue];
}
If you put it in a file named inputfile.dot you can get the resulting image file by using the command neato -Tpng inputfile.dot > outfile.png.
Now a couple of comments on how it works: The code building the tree with A, B, C, D, E, Item1, Item2, Item3 is straightforward (the attributes merely set the colors and box styles). The trick to get the lines straight and orthogonal consists of 1) adding invisible nodes with zero size to the graph, and 2) positioning all objects in absolute coordinates on the canvas. The auxiliary nodes D1, D2, D3, D4, D5, D6, D7 are needed for step 1) and the pos="x,y!" options are needed for step 2). Note, that you need the ! sign at the end of the pos command since otherwise the positions would not be considered final and the layout would still get changed.
You can add additional nodes by first positioning a new node (by using the code for the nodes A ... Item3 as a template), adding an invisible, auxiliary node (with pos such that all connections to and from it are orthogonal) and then adding the connection to the graph via <StartingNode> -- <AuxiliaryNode> -- <NewNode>.
Still another version using splines=ortho, which needs less hidden nodes and gives similar visual result.
digraph example {
splines=ortho;
ranksep=0.05;
node[shape=box, color=lightblue, style=filled];
A;B;C;D;E;
node[shape=none, color=none, style=solid];
i1[label="Item 1"];
i2[label="Item 2"];
i3[label="Item 3"];
node[label="", width=0, height=0];
edge[arrowhead=none, color=blue];
n1; n2; n3; n4; n5;
{rank=same; B; C;}
A -> n1;
n1 -> B;
n1 -> C;
{rank=same; n2; D;}
B -> n2;
n2 -> D;
{rank=same; n3; i1;}
D -> n3;
n3 -> i1;
{rank=same; n4; E;}
n2 -> n4;
n4 -> E;
{rank=same; n5; i2;}
E -> n5;
n5 -> i2;
{rank=same; n6; i3;}
i2 -> n6;
n6 -> i3;
}

Resources