I was going through a sum on geeksforgeeks.com for adding two linked lists. And I am confused in the answer provided.
Node addTwoLists(Node first, Node second) {
Node res = null; // res is head node of the resultant list
Node prev = null;
Node temp = null;
int carry = 0, sum;
while (first != null || second != null) //while both lists exist
{
// Calculate value of next digit in resultant list.
// The next digit is sum of following things
// (i) Carry
// (ii) Next digit of first list (if there is a next digit)
// (ii) Next digit of second list (if there is a next digit)
sum = carry + (first != null ? first.data : 0)
+ (second != null ? second.data : 0);
// update carry for next calulation
carry = (sum >= 10) ? 1 : 0;
// update sum if it is greater than 10
sum = sum % 10;
// Create a new node with sum as data
temp = new Node(sum);
// if this is the first node then set it as head of
// the resultant list
if (res == null) {
res = temp;
} else // If this is not the first node then connect it to the rest.
{
prev.next = temp;
}
// Set prev for next insertion
prev = temp;
// Move first and second pointers to next nodes
if (first != null) {
first = first.next;
}
if (second != null) {
second = second.next;
}
}
if (carry > 0) {
temp.next = new Node(carry);
}
// return head of the resultant list
return res;
}
I understand that we have created three Nodes res, prev and temp and I don't understand how each one of them are getting updated simultaneously.
if (res == null) {
res = temp;
} else // If this is not the first node then connect it to the rest.
{
prev.next = temp;
}
Like here, how the 2nd element would be added in res when we are adding it in prev.next.
And below :
if (carry > 0) {
temp.next = new Node(carry);
}
If we are adding the last element in temp, how will it reflect in res?
The code seems to be working but I am having a hard time understanding this concept.
Please help. Thanks in advance.
res, prev and temp are references to a Node. When you write something like res = tmp; it means that now res and tmp refer to the same Node instance, and any changes made to this instance using, for example, res reference will remain when you use tmp reference.
here is the same code but with additional comments to try to help explain what is happening. This code appears to be taking two head nodes from link lists where each node contain a single digit, then adding the digits together to create a new list of single digits (e.g. 1->2->3 and 5->6->7->8 with = 1+5->2+6->3+7->0+8. Note that the third set results in a carry over so the final values in the returned list would be 6->8->0->9).
Thus, this code is not adding to two link lists together, it is adding the data contained
in each of the nodes of the two lists and putting the result into a third list.
My additional comments in the code are prefixed with WCK -
Node addTwoLists(Node first, Node second) {
Node res = null; // res is head node of the resultant list
Node prev = null;
Node temp = null;
int carry = 0, sum;
while (first != null || second != null) //while both lists exist WCK actually this is While at least one of the lists exists, I believe the comment is wrong and the code is right
{
// Calculate value of next digit in resultant list.
// The next digit is sum of following things
// (i) Carry
// (ii) Next digit of first list (if there is a next digit)
// (ii) Next digit of second list (if there is a next digit)
sum = carry + (first != null ? first.data : 0)
+ (second != null ? second.data : 0);
// update carry for next calulation
carry = (sum >= 10) ? 1 : 0; // WCK - assumes sum <20; is only carrying at most 1
// update sum if it is greater than 10
sum = sum % 10;
// Create a new node with sum as data
temp = new Node(sum);
// if this is the first node then set it as head of
// the resultant list
// WCK - the first time through the loop, res will be null
// WCK - each subsequent time through the loop, the else is invoked to link the new node to the one from the previous iteration thus linking them
if (res == null) {
res = temp; //WCK - as #ardenit says, both res and temp point to the same node at this point
} else // If this is not the first node then connect it to the rest.
{
prev.next = temp;
}
// Set prev for next insertion
// WCK - now they are starting to set up for the next iteration.
// WCK - the first time through, res, prev and temp all point to the same node after this statement is executed.
prev = temp;
// Move first and second pointers to next nodes
if (first != null) {
first = first.next;
}
if (second != null) {
second = second.next;
}
// WCK - the first time through the loop, both of the lists passed in
// have been advanced to the next node in their respective lists.
// res and prev will point to the temp. As the next iteration of the loop
// starts, temp will be pointed to a new node while res and prev will
// still point to the same node created in the first iteration. As the
// second iteration executes, prev is set to point to the new temp
// where you see (prev.next = temp) and then prev is advanced to the
// this new node as well. res will not be changed again (it is only set
// once in the first iteration)
}
// WCK - now that the loop is finished, there may be a final carry value
if (carry > 0) {
temp.next = new Node(carry);
}
// return head of the resultant list
return res;
}
Related
I'm trying to delete a given Node from a Linked List. I don't know why my code is not working. Any hints?
So I have [11,21,31,41] and they are asking me to delete the node at index 2 in this case 31. So far I have this:
public void delete (int k) {
//[ 11 21 31 41 ].delete( 2 ): expected=[ 11 21 41 ]
if (k < 0 || k >= N) throw new IllegalArgumentException ();
for(Node x = first; x != null; x = x.next) {
//deletes node
if(x.item == k){
x = x.next;
}
if(x.item <= k){
x = x.next.next;
}
}
}
Can someone tell me please why is this not working? Thank you
You could move nodes using next k times. Store a temporary int and a previous node. Decrement the temporary int each time you call next(). Once you are at 0 (the desired element), remove by setting the previous node's next pointer to x's next pointer, and then set x to null.
I think in your code you are missing the part where pointers are set.
For example:
(1) -> (2) -> (3)
To remove (2), set (1).next = (3) and (2) = null. This will get:
(1) -> (3)
There are a couple of things going wrong here, and I encourage you to work on some println debugging to better understand the issues as you develop.
Assuming the item field is the value of the Node, you're comparing that value of a Node to the index of said Node (e.g. x.item == k).
The general logic that you're going to want to follow is, "if the Node the iterator is pointing to is the next Node in my list, set my next to its next."
In your code you are comparing the value of node with the index you passed. This comparison will always have index less than value in node. Also after that you are not updating the node when you assume the code is correct.
Below code should give you the result.
public void delete (int k)
{
//[ 11 21 31 41 ].delete( 2 ): expected=[ 11 21 41 ]
if (k < 0 || k >= N) throw new IllegalArgumentException ();
int count = 0;//Assuming index starts from 0
Node prev;
for(Node x = first; x != null; x = x.next)
{
//deletes node
count++;
if(count<k)
{
prev = x;
continue;
}
else
{
prev.next = x.next;
x.next = null;
break;
}
}
if(count>k || count<k)
{
System.out.println("No element with index k");
}
}
#vase is correct saying
Assuming the item field is the value of the Node, you're comparing
that value of a Node to the index of said Node (e.g. x.item == k).
some example code that could fix this
public void delete(int k){
Node n = first;
for(int i = 0; i < k-1; i++){ // this loop finds the node right before the
n=n.next; // index to use to delete the desired index.
}
n.next = n.next.next; // delete command
}
I'm trying to figure out the minimum depth to a leaf node using breadth first search. I have the following basic structure
public int BFS(Node root){
if (root == null) return 0;
Queue<Node> q = new LinkedList<Node>();
int min = 1;
q.clear(); // I saw this in a queue example, unsure if needed
q.add(root);
while (! q.isEmpty()){
Node n = q.remove();
if (n.left != null) q.add(n.left);
if (n.right != null) q.add(n.right);
}
}
I'm not sure where to update the min height counter. I had thought about placing it inside the if statements as temp loop variables l & r where I would set them to 1 if the left or right is not null, 0 else. Then add the min of these 2 to the min height but this only works if I'm at one level above the leafs.
The idea should be something like:
First node added to the queue should have distance = 1.
For new nodes added to the queue: distance = actual node distance + 1
When you find a leaf, you return actual node distance. END.
In pseudocode:
root.depth := 1
q := create queue
q.add(root)
while q is not empty
Node n := q.dequeue()
if (n is leaf) then
return n.depth
if (n.left is not null) then
n.left.depth := n.depth + 1
q.add(n.left)
if (n.right is not null) then
n.right.depth := n.depth + 1
q.add(n.right)
return 0
You could use a queue of pairs (node, depth). Since the search is BFT, the first leaf contains the minimum depth.
Based on your code, the algorithm would be something like that (pseudo java code):
public int BFS(Node root)
{
if (root == null)
return 0;
Queue<Pair<Node,int>> q = new LinkedList<Pair<Node,int>>();
q.add(new Pair(root, 0));
while (! q.isEmpty()) {
Pair p = q.remove();
Node n = p.getFirst();
if (n.left == null && n.right == null) // is this a leaf?
return p.getSecond(); // yes! ==> p.getSecond() is its min depth
if (n.left != null)
q.add(new Pair(n.left, p.getSecond() + 1));
if (n.right != null)
q.add(new Pair(n.right, p.getSecond() + 1));
}
}
Of course, you need the Pair class, but I leave to you these details
Generally in BFS, your nodes have a distance field. the roots distance is zero, then whenever you add a new node to the queue, you set its distance to n.distance+1
I'm working on my Quick Sort exercise that uses a LinkedList to sort, (I know it's not efficient and really pointless, it's for class). I understand how the Quick Sort method works, as well as the median of three strategy. My code is working properly for only certain lengths however, for example.
This works fine:
7 6 5 4 3 2 1, pivot = 4
7 6 5, pivot = 6 | 3 2 1, pivot = 2
Now, for anything that isn't like that, ie.
5 4 3 2 1, pivot = 3
5 4, throws an error | 2 1 throws an error.
Here is the code that I have:
Finds the middle node in the LinkedList.
public Node findMiddleNode() {
Node node1 = first;
Node node2 = first;
while(node2.getNext() != null && node2.getNext().getNext()!= null) {
node1 = node1.getNext();
node2 = node2.getNext().getNext();
}
return node1;
}
Finds the median of the first, middle and last nodes.
public Node medianOfThree() {
Node firstNode = first;
Node lastNode = last;
Node middleNode = findMiddleNode();
if((firstNode.getData() - middleNode.getData()) * (lastNode.getData() - firstNode.getData()) >= 0) {
return firstNode;
} else if((middleNode.getData() - firstNode.getData()) * (lastNode.getData() - middleNode.getData()) >= 0) {
return middleNode;
} else {
return lastNode;
}
}
Removes the pivots from the list, this is the method which breaks.
private Node chooseAndRemovePivot() {
Node pivot = medianOfThree();
Node previous = first;
// If the pivot is the first Node.
if(previous == pivot) {
first = previous.getNext();
}
// Gets the last Node before the pivot
while(previous.getNext() != pivot) {
previous = previous.getNext();
}
previous.setNext(pivot.getNext());
pivot.setNext(null);
size--;
if (size == 0)
last = null;
return pivot;
}
Can anyone point out what's going wrong here, I'm sure it's a simple mistake that I am making.
EDIT: Solution;
In the method chooseAndRemovePivot();
// If the pivot is the first Node.
if(previous == pivot) {
first = previous.getNext();
} else {
// Gets the last Node before the pivot
while(previous.getNext() != pivot) {
previous = previous.getNext();
}
}
This gets it working for all lengths.
The medianOfThree function will return pivot == first for lists of length 2. Thus this code:
// Gets the last Node before the pivot
while(previous.getNext() != pivot) {
previous = previous.getNext();
}
...will never find the terminal condition and instead assign previous = null when it reaches the end of the list. Then the next iteration will throw a NullPointerException.
I beleive the error is in your findMiddleNode() function. Specifically, node2.getNext.getNext() doesn't ever check that node2.getNext() is not null
in a list with an even number of items, node2.getNext().getNext() will run off the end. effectively reducing the statement to Null.getNext() which is an error.
For example using the list
first -> a -> b -> null
First node1 and node2 are set to "first.
Then node1 becomes a, and node2 becomes b.
Then node1 becomes b and node2 becomes b.getNext().getNext() or in other words Null.getNext.
The algorithm works for odd length lists, because node2.getNext().getNext() will always land on the null
I'm trying to implement a Min Heap in Java, but I'm having issues with inserting and removing elements (inserting at the end, removing the root as min). It seems to work for the most part (I use a program to visually display the heap and have been printing out the new roots when min has been removed, things like that).
My problem is, for some reason the root won't switch with a new item when a new item is added, but I can't figure out why at all. Also, it seems this is only the problem when there are a lot of duplicates, the heap doesn't seem completely capable of staying in order (the parent is smaller than the children). For the most part, it does. Only occasionally it doesn't, and to me it seems random.
This is done with generics, and basically following most algorithms. Everything else I know for a fact works, it's definitely a problem with these two methods.
public void insert(T e) {
if (size == capacity)
increaseSize(); //this works fine
last = curr; //keeping track of the last index, for heapifying down/bubbling down when removing min
int parent = curr/2;
size++; //we added an element, so the size of our data set is larger
heap[curr] = e; //put value at end of array
//bubble up
int temp = curr;
while (temp > 1 && ((Comparable<T>) heap[temp]).compareTo(heap[parent]) < 0) { //if current element is less than the parent
//integer division
parent = temp/2;
swap(temp, parent); //the swapping method should be correct, but I included it for clarification
temp = parent; //just moves the index value to follow the element we added as it is bubbled up
}
curr++; //next element to be added will be after this one
}
public void swap(int a, int b){
T temp = heap[a];
heap[a] = heap[b];
heap[b] = temp;
}
public T removeMin() {
//root is always min
T min = heap[1];
//keep sure array not empty, or else size will go negative
if (size > 0)
size--;
//put last element as root
heap[1] = heap[last];
heap[last] = null;
//keep sure array not empty, or else last will not be an index
if (last > 0)
last--;
//set for starting at root
int right = 3;
int left = 2;
int curr = 1;
int smaller = 0;
//fix heap, heapify down
while(left < size && right < size){ //we are in array bounds
if (heap[left] != null && heap[right] != null){ //so no null pointer exceptions
if (((Comparable<T>)heap[left]).compareTo(heap[right]) < 0) //left is smaller
smaller = left;
else if (((Comparable<T>)heap[left]).compareTo(heap[right]) > 0) //right is smaller
smaller = right;
else //they are equal
smaller = left;
}
if (heap[left] == null || heap[right] == null)//one child is null
{
if (heap[left] == null && heap[right] == null)//both null, stop
break;
if (heap[left] == null)//right is not null
smaller = right;
else //left is not null
smaller = left;
}
if (((Comparable<T>)heap[curr]).compareTo(heap[smaller]) > 0)//compare smaller or only child
{
swap(curr,smaller); //swap with child
curr = smaller; //so loop can check new children for new placement
}
else //if in order, stop
break;
right = 2*curr + 1; //set new children
left = 2*curr;
}
return min; //return root
}
Any variables not declared in the methods are global, and I know a couple of things are probably redundant, like the whole current/last/temp situation in add, so I'm sorry about that. I tried to make all names self explanatory and explain all the checks I did in removeMin. Any help would be insanely appreciated, I've gotten as far as I can looking things up and debugging. I think I'm just fundamentally missing something here.
Just to help you debug, you should simplify the code. There is something strange going on with 'last' variable. Also in 'insert' when you do the loop, probably temp should go to 0, that is
while (temp >= 0 &&......
Consider:
Node reverse(Node head) {
Node previous = null;
Node current = head;
Node forward;
while (current != null) {
forward = current.next;
current.next = previous;
previous = current;
current = forward;
}
return previous;
}
How exactly is it reversing the list?
I get that it first sets the second node to forward. Then it says current.next is equal to a null node previous. Then it says previous is now current. Lastly current becomes forward?
I can't seem to grasp this and how it's reversing. Can someone please explain how this works?
You reverse the list iteratively and always have the list in the interval [head, previous] correctly reversed (so current is the first node that has its link not set correctly). On each step you do the following:
You remember the next node of current so that you can continue from it
You set the link of current to be pointing to previous, which is the correct direction if you think about it
You change previous to be current, because now current also has its link set correctly
You change the first node that does not have its link set correctly to be the one remembered in the first step
If you do that for all the nodes, you can prove (with induction for instance) that the list will be correctly reversed.
The code simply walks the list and inverts the links until it reaches the previous tail, which it returns as the new head.
Before:
Node 1 (Head) -> Node 2 -> Node 3 -> Node 4 (Tail) -> null
After:
null <- Node 1 (Tail) <- Node 2 <- Node 3 <- Node 4 (Head)
The easiest way to think about it is to think like this:
First add the head of the list to a new linked list.
Keep iterating through the original and keep adding the nodes before the head of the new linked list.
Diagram:
Initially:
Original List -> 1 2 3 4 5
New List -> null
1st Iteration
Original List -> 1 2 3 4 5
New List -> 1->null [head shifted to left, now newHead contains 1 and points to null]
2nd Iteration
Original List -> 1 2 3 4 5
New List -> 2-> 1->null [head shifted to left, now newHead contains 2 and points to next node which is 1]
3rd Iteration
Original List -> 1 2 3 4 5
New List ->3 -> 2-> 1->null [head shifted to left, now newHead contains 2 and points to next node which is 1]
Now it keeps looping through till the end. So finally the new list becomes:
New List-> 5 -> 4 -> 3 -> 2 -> 1 -> null
The code for the same should be like this (made it easy to understand):
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public ListNode reverseList(ListNode head) {
if(head == null) {
return null;
}
if(head.next == null) {
return head;
}
ListNode current = head;
ListNode previous = new ListNode(head.val);
previous.next = null;
while(current.next != null) {
current = current.next;
previous = addBeforeHead(current, previous);
}
return previous;
}
private ListNode addBeforeHead(ListNode node, ListNode head) {
if (node == null) return null;
ListNode temp = new ListNode(node.val);
temp.next = head;
head = temp;
return head;
}
public Node getLastNode()
{
if(next != null)
return next.getLastNode();
else
return this;
}
public Node reverse(Node source)
{
Node reversed = source.getLastNode();
Node cursor = source;
while(cursor != reversed)
{
reversed.addNodeAfter(cursor.getInfo());
cursor = cursor.getNodeAfter();
}
source = reversed;
return source;
}
I call it "cherry picking". The idea is to minimize the number of swaps. Swapping happens between a near and far index. It's a twp-pass algorithm.
(Odd length) A -> B -> C -> D -> E
(Even length) A -> B -> C -> D
Pre-Condition: N >= 2
Pass 1: Count N, the number of elements
Pass 2:
for(j=0 -> j<= (N/2 -1))
{
swap(j, (N-1)-j)
}
Example 1:
For above Odd length list, N = 5 and there will be two swaps
when j=0, swap(0, 4) // Post swap state: E B C D A
when j=1, swap(1, 3) // Post swap state: E D C B A
The mid point for odd length lists remains intact.
Example 2:
For above Even length list, N = 4 and there will be two swaps
when j=0, swap(0, 3) // Post swap state: D B C A
when j=1, swap(1, 2) // Post swap state: D C B A
Swapping applies to data only, not to pointers, and there might be any sanity checks missed, but you got the idea.
list_t *reverse(list_t *a)
{
list_t *progress = NULL;
while(a)
{
list_t *b; //b is only a temporary variable (don't bother focusing on it)
b = a->next;
a->next = progress; // Because a->next is assigned to another value,
// we must first save a->next to a different
// variable (to be able to use it later)
progress = a; // progress is initially NULL (so a->next = NULL
// (because it is the new last element in the list))
a = b; // We set a to b (the value we saved earlier, what
// a->next was before it became NULL)
/*
Now, at the next iteration, progress will equal a, and a will equal b.
So, when I assign a->next = progress, I really say, b->next = a.
and so what we get is: b->a->NULL.
Maybe that gives you an idea of the picture?
What is important here is:
progress = a
and
a = b
Because that determines what a->next will equal:
c->b->a->0
a's next is set to 0
b's next is set to a
c's next is set to b
*/
}
return progress;
}
The basic idea is to detach the head node from the first list and attach it to the head of a second list. Keep repeating until the first list is empty.
Pseudocode:
function reverseList(List X) RETURNS List
Y = null
WHILE X <> null
t = X.next
X.next = Y
Y = X
X = t
ENDWHILE
RETURN Y
ENDfunction
If you wish to leave the original list undisturbed then you can code a copying version recursively with the use of a helper function.
function reverseList(List X) RETURNS List
RETURN reverseListAux(X, null)
ENDfunction
function reverseListAux(List X, List Y) RETURNS List
IF X = null THEN
RETURN Y
ELSE
RETURN reverseListAux(X.next, makeNode(X.data, Y))
ENDfunction
Note that the helper function is tail recursive. This means that you can create a copying reversal using iteration.
function reverseList(List X) RETURNS List
Y = null
WHILE X <> null
Y = makeNode(x.data, Y)
X = X.next
ENDWHILE
RETURN Y
ENDfunction
Reversing a singly-linked list using iteration:
current = head // Point the current pointer to the head of the linked list
while(current != NULL)
{
forward = current->link; // Point to the next node
fforward = forward->link; // Point the next node to next node
fforward->link = forward; // 1->2->3,,,,,,,,,this will point node 3 to node 2
forward->link = current; // This will point node 2 to node 1
if(current == head)
current->link = NULL; // If the current pointer is the head pointer it should point to NULL while reversing
current = current->link; // Traversing the list
}
head = current; // Make the current pointer the head pointer
Implementation of a singly-linked list reversal function:
struct Node
{
int data;
struct Node* link;
}
Node* head = NULL;
void reverseList()
{
Node* previous, *current, *next;
previous = NULL;
current = head;
while(current != NULL)
{
next = current-> link;
current->link = previous;
previous = current;
current = next;
}
head = previous;
}
Here is a simple function to reverse a singly linked list
// Defining Node structure
public class Node {
int value;
Node next;
public Node(int val) {
this.value=val;
}
}
public LinkedList reverse(LinkedList list) {
if(list==null) {
return list;
}
Node current=list.head;
Node previous=null;
Node next;
while(current!=null) {
next=current.next;
current.next=previous;
previous=current;
current=next;
}
list.head=previous;
return list;
}
For better understanding, you can watch this video https://youtu.be/6SYVz-pnVwg
If you want to use recursion:
class Solution {
ListNode root=null;
ListNode helper(ListNode head)
{
if (head.next==null)
{ root= head;
return head;}
helper (head.next).next=head;
head.next=null;
return head;
}
public ListNode reverseList(ListNode head) {
if (head==null)
{
return head;
}
helper(head);
return root;
}
}
public void reverseOrder() {
if(head == null) {
System.out.println("list is empty");
}
else {
Node cn = head;
int count = 0;
while (cn != null) {
count++;
cn = cn.next;
}
Node temp;
for(int i = 1; i<=count; i++) {
temp = head;
for(int j = i; j<count; j++) {
temp = temp.next;
}
System.out.print(temp.data+" ->");
}
System.out.print("null");
}
}