Find duplicates values in the linked list (Simple convert into difficult) - data-structures

This seems to be a very simple question. I had been asked by the interviewer to find the duplicate element in the linked list, and then he told me Some of the constraints that made the question difficult for me. the constraint is you have to traverse the linked list only one time.
Resources
The only resource I have available is another linked list.
BONUS
Remove that Element if you can traverse it only one time,
The time should be O(N)
Q1: I can't find the Answer, I don't know if the solution exists or not or he was just confusing me... if yes, how can that be possible?

You could use a HashMap, If this were to be implemented in Java we could use Map datastructure
The Map stores Key-Value Pairs and the elements can be accessed almost O(1), therefore this snippet runs in O(n)
private void removeDuplicates(final Node node) {
Map<Integer, Boolean> map = new HashMap<Integer, Boolean>();
Node n = node;
Node prev = null;
while (n != null) {
if (map.get(n.data) == null) {
map.put(n.data, true);
}
else {
System.out.println("Found Duplicate of: "+n.data);
/*To remove duplicates. do this
if (n.next != null) {
n.data = n.next.data;
n.next = n.next.next;
continue;
}
if (prev != null) {
prev.next = n.next;
}
*/
}
prev = n;
n = n.next;
}
}

Related

find out which sorting alogorithm used in this function

Hi can someone help me out which sorting algorithm used in this function
public void sortList() {
Node current = null, index = null;
int temp;
//Check whether list is empty
if(head == null) {
return;
}
else {
//Current will point to head
for(current = head; current.next != null; current = current.next) {
//Index will point to node next to current
for(index = current.next; index != null; index = index.next) {
//If current's data is greater than index's data, swap the data of current and index
if(current.data > index.data) {
temp = current.data;
current.data = index.data;
index.data = temp;
}
}
}
}
}
By the way it is Doubly Link List
The current node is fixed and then iteration is done from next node to the end(via index variable), at the end of one iteration of outer loop the node pointed to by current has correct value, then the current is progressed to next node.
This is Selection Sort, the most elementary sort
Fun fact : although slow because of complexity O(n^2) selection sort can be used when the write operation is expensive because it only swaps max n times for a list of size n

Algorithm to check a linked-list for loops

I want to find an algorithm which checks a linked-list with n elements for consistency. The linked-list uses a dummy head (also known as sentinel-node). The algorithm needs to run in O(n) time and is allowed to use O(1) extra space apart from the space needed to iterate through the list. The size of the list is unknown. In addition it's forbidden to modify the list.
A list counts as inconsistent if there is a list item which points at a previous list item.
First I thought about storing the first element and then iterate through the list while comparing the current element with the first one.
Does the list provide a Size property that tells you how many elements it contains (n) without traversing it?
If it does then a simple solution that meets all your big-O requirements is to attempt to traverse the list, counting the elements as you go. If the count exceeds the expected number of elements in the list then it has a loop.
Pseudo-code would look something like this:
bool isConsistent (List list)
{
bool consistent = true;
Node node = list.Sentinel.Next;
int count = 0;
while (node != list.Sentinel && consistent)
{
count++;
if (count > list.Size)
consistent = false;
node = node.Next;
}
return consistent;
}
That completes in O(n) and uses O(1) storage.
Floyd's "Tortoise and Hare" algorithm does what you need and only needs a small modification to work with your dummy head/tail (sentinel) node.
Here is how I would write the pseudo-code:
bool IsConsistent (List list)
{
Node tortoise = list.Sentinel.Next;
Node hare = tortoise.Next;
while (tortoise != list.Sentinel && hare != list.Sentinel)
{
if (tortoise == hare)
return false;
tortoise = tortoise.Next;
hare = hare.Next.Next;
}
return true;
}
You will need some RAM for that if you don't have a Visited property on each item in the linked list.
If you have a Visited property you will first need to clear it before running the algorithm. This will probably not fit your big-O requirements.
It's not clear what you mean with "points at previous list item". Is equal by reference (object) or same value/set of property values (struct)? I assume reference. The code below can easily be modified to handle structs as well.
static void Main(string[] args)
{
var list = BuildALinkedListFromSomeData();
var isConsitent = IsConsistent(list);
}
static bool IsConsistent(LinkedList<Item> list)
{
var visited = new List<LinkedListNode<Item>>()
var runner = list.First;
while(runner != null)
{
if (visited.Contains(runner))
return false;
visited.Add(runner);
runner = runner.Next;
}
return true;
}
A O(n) solution that uses an existing numeric VisitCounter that already uses storage space (no additional storage needed):
static bool IsConsistent(LinkedList<Item> list)
{
var runner = list.First;
if (runner == null)
return false; // Assume consistent if empty
var consistent = true;
var runId = runner.Value.VisitCount;
while (runner != null)
{
// Does the traversed item match the current run id?
if(runner.Value.VisitCount > runId)
{
// No, Flag list as inconsistent. It must have been visited previously during this run
consistent = false;
// Reset the visit count (so that list is ok for next run)
runner.Value.VisitCount = runId;
}
// Increase visit count
runner.Value.VisitCount++;
// Visit next item in list
runner = runner.Next;
}
return consistent;
}
This makes changes to the content of an item in the list, but not the list itself. If you're not allowed to change the content of an item in the list, then of course this is not a solution either. Well, second-thought, this is not a possible solution at all. When inconsistent, your list is circular and the last algorithm will never finish :)
You will then have to traverse the list backwards from each visited item in your list and this will break your O(n+1) requirement.
Conclusion: Not so Mission Impossible if Count is available. See GrahamS' answer
Here is my solution for the second question.
IsConsistent(LinkedList<Item> list) :N
slow = List.Sentinel.next :Element
fast = slow.next :Element
isConsistent = true :boolean
while(fast != list.Sentinel && fast.next != list.Sentinel && isConsistent) do
if(slow == fast)
isConsistent = false
else
slow:= slow.next
fast:= fast.next.next
od
if(isConsistent)
return 0
else
position = 0 : N
slow:= list.Sentinel
while(slow != fast) do
slow:= slow.next
fast:= fast.next
position:= position + 1
od
return position
Basically, pointing a previous item means having a loop inside the list. In this case, loop check is seem appropriate.
At first I didn't thought about using list.Sentinel. Now I got a new idea.
IsConsistent(LinkedList<Item> list) :boolean
slow = List.Sentinel.next :Element
fast = slow.next :Element
while(slow != list.Sentinel && fast != list.Sentinel) do
if(slow == fast) return false
else
slow:= slow.next
fast:= fast.next.next
od
return true

working with pointers and linkedLists: how to iterate over a linked list, change and compare keys

I am asked to implement an algorithm based upon the data structure of a linkedList in the form of pseudocode.
Unfortunately I have a Python/Java background and thus no experience with pointers.
Could someone explain me how I would iterate over a doublyLinkedList, change and compare values of elements.
From what I have understood so far, i would do something like this.: to have an iteration over each element.
for L.head to L.tail
But how would I then access the current object in the list analogous to A[i] for i to L.length?
As the order of a linkedList is determined by pointers rather than indices in a linkedList can I simply do things like currentObj.prev.key = someVal or currentObj.key < currentObj.prev.key or is there some other wokflow to work with individual elements?
Again, I am obviously stuck as I lack an basic understanding on how to deal with pointers.
Cheers,
Andrew
So basically the data structures are:
Node:
node {
node next;//"single link"
node prev;//for "doubly"...
}
and List:
list {
node head;//for singly linked, this'd be enough
node tail;//..for "doubly" you "point" also to "tail"
int/*long*/ size; //can be of practical use
}
The (common) operations of a list:
Creation/Initialization:
list:list() {
head = null;
tail = null;
size = 0;
}
Add a node at the first position:
void:addFirst(node) {
if(isEmpty()) {
head = node;
tail = node;
size = 1;
} else {
head.prev = node;
node.next = head;
head = node;
size++;
}
}
// ..."add last" is quite analogous...
"is empty", can be implemented in different ways..as long as you keep the invariant
bool:isEmpty() {
return size==0;
//or return head==null ... or tail==null
}
"add a node at position i":
void:add(i, node) {
assert(i>=0 && i <=size);//!
if(isEmpty() || i == 0) {
addFirst(node);
} else if (i == size) {
addLast(node);
} else {//here we could decide, whether i is closer to head or tail, but for simplicity, we iterate "from head to tail".
int j = 1;
node cur = head.next; //<- a "cursor" node, we insert "before" it ;)
while(j < i) {//1 .. i-1
cur = cur.next;// move the cursor
j++;//count
}
//j == i, cur.next is not null, curr.prev is not null, cur is the node at currently i/j position
node.prev = cur.prev;
cur.prev.next = node;
cur.prev = node;
node.next = cur;
}
//don't forget the size:
size++;
}
Delete(node) is easy!
"Delete at position", "find node", "get node by position", etc. should use a similar loop (as add(i, node))...to find the correct index or node.
The strength/advantage of a doubly (comparing to a singly) linked list, is that it can iterate as "forth" as "back". To use this advantage (it is only advantageous on index-based operations, for "find(node)" e.g. you still don't know where to start/iterate best), you determine whether pos is closer to head(0) or to tail(size-1), and start&route your iteration accordingly.
...What else operations are you intereseted in (detail)?

Implementing the Dutch National Flag Program with Linked Lists

I wanted to sort a linked list containing 0s, 1s or 2s. Now, this is clearly a variant of the Dutch National Flag Problem.
http://en.wikipedia.org/wiki/Dutch_national_flag_problem
The algorithm for the same as given in the link is:
"Have the top group grow down from the top of the array, the bottom group grow up from the bottom, and keep the middle group just above the bottom. The algorithm stores the locations just below the top group, just above the bottom, and just above the middle in three indexes. At each step, examine the element just above the middle. If it belongs to the top group, swap it with the element just below the top. If it belongs in the bottom, swap it with the element just above the bottom. If it is in the middle, leave it. Update the appropriate index. Complexity is Θ(n) moves and examinations."
And a C++ implementation given for the same is:
void threeWayPartition(int data[], int size, int low, int high) {
int p = -1;
int q = size;
for (int i = 0; i < q;) {
if (data[i] == low) {
swap(data[i], data[++p]);
++i;
} else if (data[i] >= high) {
swap(data[i], data[--q]);
} else {
++i;
}
}
}
My only question is how do we traverse back in a linked list like we are doing here in an array?
A standard singly-linked list doesn't allow you to move backwards given a linked list cell. However, you could use a doubly-linked list, where each cell stores a next and a previous pointer. That would let you navigate the list forwards and backwards.
However, for the particular problem you're trying to solve, I don't think this is necessary. One major difference between algorithms on arrays and on linked lists is that when working with linked lists, you can rearrange the cells in the list to reorder the elements in the list. Consequently, the algorithm you've detailed above - which works by changing the contents of the array - might not actually be the most elegant algorithm on linked lists.
If you are indeed working with linked lists, one possible way to solve this problem would be the following:
Create lists holding all values that are 0, 1, or 2.
Remove all cells from the linked list and distribute them into the list of elements that are equal to 0, 1, or 2.
Concatenate these three lists together.
This does no memory allocation and purely works by rearranging the linked list cells. It still runs in time Θ(n), which is another plus. Additionally, you can do this without ever having to walk backwards (i.e. this works on a singly-linked list).
I'll leave the complete implementation to you, but as an example, here's simple C++ code to distribute the linked list cells into the zero, one, and two lists:
struct Cell {
int value;
Cell* next;
}
/* Pointers to the heads of the three lists. */
Cell* lists[3] = { NULL, NULL, NULL };
/* Distribute the cells across the lists. */
while (list != NULL) {
/* Cache a pointer to the next cell in the list, since we will be
* rewiring this linked list.
*/
Cell* next = list->next;
/* Prepend this cell to the list it belongs to. */
list->next = lists[list->value];
lists[list->value] = list;
/* Advance to the next cell in the list. */
list = next;
}
Hope this helps!
As others have said, there is no way to "back up" in a linked list without reverse links. Though it's not exactly an answer to your question, the sort can be easily accomplished with three queues implementing a bucket sort with three buckets.
The advantage of queues (vice pushing on stacks) is that the sort is stable. That is, if there are data in the list nodes (other than the 0,1,2-valued keys), these will remain in the same order for each key.
This is only one of many cases where the canonical algorithm for arrays is not the best for lists.
There is a very slick, simple way to implement the queues: circularly linked lists where the first node, say p, is the tail of the queue and consequently p->next is is the head. With this, the code is concise.
#include <stdio.h>
#include <stdlib.h>
typedef struct node_s {
struct node_s *next;
int val;
int data;
} NODE;
// Add node to tail of queue q and return the new queue.
NODE *enqueue(NODE *q, NODE *node)
{
if (q) {
node->next = q->next;
q->next = node;
}
else node->next = node;
return node;
}
// Concatenate qa and qb and return the result.
NODE *cat(NODE *qa, NODE *qb)
{
NODE *head = qa->next;
qa->next = qb->next;
qb->next = head;
return qb;
}
// Sort a list where all values are 0, 1, or 2.
NODE *sort012(NODE *list)
{
NODE *next = NULL, *q[3] = { NULL, NULL, NULL};
for (NODE *p = list; p; p = next) {
next = p->next;
q[p->val] = enqueue(q[p->val], p);
}
NODE *result = cat(q[0], cat(q[1], q[2]));
// Now transform the circular queue to a simple linked list.
NODE *head = result->next;
result->next = NULL;
return head;
}
int main(void)
{
NODE *list = NULL;
int N = 100;
// Build a list of nodes for testing
for (int i = 0; i < N; ++i) {
NODE *p = malloc(sizeof(NODE));
p->val = rand() % 3;
p->data = N - i; // List ends up with data 1,2,3,..,N
p->next = list;
list = p;
}
list = sort012(list);
for (NODE *p = list; p; p = p->next)
printf("key val=%d, data=%d\n", p->val, p->data);
return 0;
}
This is now a complete simple test and it runs just fine.
This is untested. (I will try to test it if I get time.) But it ought to be at least very close to a solution.
Using a doubly linked list. If you have already implemented a linked list object and the related link list node object, and are able to traverse it in the forward direction it isn't a whole bunch more work to traverse in the reverse direction.
Assuming you have a Node object somewhat like:
public class Node
{
public Node Next;
public Object Value;
}
Then all you really need to do is change you Node class and you Insert method(s) up a little bit to keep track of of the Node that came previously:
public class Node
{
public Node Next;
public Node Previous;
public Object Value;
}
public void Insert(Node currentNode, Node insertedNode)
{
Node siblingNode = currentNode.Next;
insertedNode.Previous = currentNode;
insertedNode.Next = siblingNode;
if(siblingNode!= null)
siblingNode.previous = insertedNode;
currentNode.next = insertedNode;
}
PS Sorry, I didn't notice the edit that included the C++ stuff so it's more C#
Works for all cases by CHANGING NODES rather than NODE DATA.. Hoping its never too late!
METHOD(To throw some light on handling corner cases):
1. Keep three dummy nodes each for 0,1,2;
2. Iterate throught the list and add nodes to respective list.
3. Make the next of zero,one,two pointers as NULL.
4. Backup this last nodes of each list.
5. Now handle 8 different possible cases to join these list and Determine the HEAD.
zero one two
0 0 0
0 0 1
0 1 0
0 1 1
1 0 0
1 0 1
1 1 0
1 1 1
An implementation of this in C++.
Node* sortList(Node *head)
{
struct Node dummyzero,dummyone,dummytwo;
dummyzero.next = dummyone.next = dummytwo.next = NULL;
struct Node *zero =&dummyzero,*one = &dummyone,*two=&dummytwo;
Node *curr = head,*next=NULL;
while(curr)
{
next = curr->next;
if(curr->data==0)
{
zero->next = curr;
zero = zero->next;
}
else if(curr->data==1)
{
one->next = curr;
one = one->next;
}
else
{
two->next = curr;
two = two->next;
}
curr = next;
}
zero->next = one->next = two->next =NULL; //Since this dummynode, No segmentation fault here.
Node *zerolast = zero,*onelast = one,*twolast = two;
zero = dummyzero.next;
one = dummyone.next;
two = dummytwo.next;
if(zero==NULL)
{
if(one==NULL)
head = two;
else
{
head = one;
onelast->next = two;
}
}
else
{
head = zero;
if(one==NULL)
zerolast->next = two;
else
{
zerolast->next = one;
onelast->next = two;
}
}
return head;
}
The idea is to use dutch flag sorting algorithm, with a slight modification:
sort 0's and 1's as per dutch flag method,
But for 2's instead of adding them at the end of list, keep them in a separate linked list.
And finally append the 2's list to the sorted list of 0's and 1's.
Node * sort012_linked_list(Node * head) {
if (!head || !head->next)
return head;
Node * head_of_2s = NULL;
Node * prev = NULL;
Node * curr = head;
while (curr) {
if (curr->data == 0) {
if (prev == NULL || prev->data == 0) {
prev = curr;
curr = curr->next;
}
else {
prev->next = curr->next;
curr->next = head;
head = curr;
curr = prev->next;
}
}
else if (curr->data == 1) {
prev = curr;
curr = curr->next;
}
else { // curr->data == 2
if (prev == NULL) {
head = curr->next;
curr->next = head_of_2s;
head_of_2s = curr;
curr = head;
}
else {
prev->next = curr->next;
curr->next = head_of_2s;
head_of_2s = curr;
curr = prev->next;
}
}
}
if (prev)
prev->next = head_of_2s;
return head;
}

Does the singularly LinkedList give output In LIFO?

I was working on a singularly-linked list. While creating my own linked list I got confused on printing the collection of nodes in my custom linked list.
I want to know, does a singularly-linked list display its collection in a LIFO manner like a stack?
below is my Own LinkedList AND node is A Class can anyone tell me Does Singular LinkedList Prints The Collection In Lifo Manner.
class MYlinklist
{
Node header;
public void Add(int a)
{
Node n = new Node();
n.element = a;
n.Next = header;
header = n;
}
public void Print()
{
Node n = new Node();
n = header;
while (n != null)
{
Console.WriteLine(n.element.ToString());
n = n.Next;
}
}
}
If you are referring to LinkedList<T>, the answer depends on how you add new members.
If you want to make the linked list iterate in LIFO, you can do so by always using AddFirst to add, and RemoveFirst to remove. This will cause it behave very much like a stack.
The nice thing about LinkedList<T>, however, is that you can add anywhere inside of the list as an O(1) operation.
Edit:
If you want this to be FIFO instead, you'll need to change how to add your nodes, and add them at the end of the list, not the start:
class MyLinkedList
{
Node header;
Node last;
public void Add(int a)
{
Node n = new Node();
n.element = a;
n.Next = null; // We'll put this at the end...
if (last == null)
{
header = n;
last = n;
}
else
{
last.Next = n;
last = n;
}
}
public void Print()
{
Node n = new Node();
n = header;
while (n != null)
{
Console.WriteLine(n.element.ToString());
n = n.Next;
}
}
}
You're adding nodes at the head of the list (note how you are always setting node.Next to the head of the list).
Then you're iterating through from the head (which is the last element inserted) to the tail.
If you want to iterate in FIFO order, you should do the following:
Maintain a reference to the tail of the list (as well as the head, which you've put in header).
When you add a node, set tail.Next to the new node, and then set tail to point to the new node.
Your iteration function can be unchanged.
Your other option is, instead of maintaining a reference to the tail, just do an iteration through the list each time. But this comes with the tradeoff of needing to go through n-1 elements to add the nth element every time, which means adding many elements is an O(n^2) operation. I would not recommend doing this, but it might be fine for a beginning if you're learning the basics and you're not sure about the tail reference manipulation. In production code, though, you should always have a head and a tail reference for linked lists.

Resources