recursiveSum(Node currentNode) {
if (currentNode == null){
System.out.println("done " );
}else{ recursiveSum(currentNode.next);
}
}
Heres the node class and the recursive method. I have tried everything that I can possibly think of to return all possible subsets... if i add the numbers {`1,2,3} to the list, the recursive method should print: {1,2,3} {1,3} {1,2} {1} {1,3} {2} {3} {0}
private static class Node {
Node next;
int number;
public Node(int numberValue) {
next = null;
number = numberValue;
}
public int getNumber() {
return number;
}
public void setData(int numberValue) {
number = numberValue;
}
public Node getNext() {
return next;
}
public void setNext(Node nextValue) {
next = nextValue;
}
}
Just as a note, recursion is not a data structure, it is an iteration technique. Assuming your linked list looks like the following, and that you are using the Java LinkedList object that contains Node objects, it's relatively simple to recurse through it.
(node 1)->(node 2)->(node N)->NULL
All you need for recursion is a base case and a way to get the next node in the linked list.
public void walk_list(LinkedList<Node> list){
//the poll method retrieves and removes the head of the list
//if the list is empty, it returns null
Node n = list.poll();
//Base case - list is empty
if(n == null){
return;
}
System.out.println(n.toString());
walk_list(list);
}
Now, if your LinkedList looks like this
(node 1)->{ (node 2), (node 3) }
(node 2)->{ (node 4) }
(node 3)->{ (node 5), (node 6) }
(node 6)->{ (node 1) }
you have a cyclic graph. There are a few ways of searching this graph, the easiest being a breadth-first search or depth-first search. Both of which can be recursive much like the given example. All you have to do is keep a list of some sort (queue, array list, etc.) to know what gets searched next, and each node in the graph should have a visited attribute that is a boolean that gets set when you get that node's children.
After clarification of the problem, have a look at this question and answer. You want to do a recursive permutation. So all you need is a Set of Integer objects.
Related
As a homework assignment I'm suppose to return the position of the second to last occurrence of a letter--to know what letter to check it is passed as a Char type parameter. What I'm searching through is a self-coded linked list. It also has to be done recursively, which I've been struggling to fully understand. Here's what I've worked out so far.
Note: If a letter appears either 0 or 1 time, return -1.
E.g.
["ababcdefb"].positionOfSecondToLastOccurrence('b') == 3
static class Node {
public Node (char item, Node next) { this.item = item; this.next = next; }
public char item;
public Node next;
}
Node first;
public int positionOfSecondToLastOccurrence (char letter) {
if (first == null)
return -1;
return positionOfSecondToLastOccurrenceHelper(letter, first, 0);
}
private int positionOfSecondToLastOccurrenceHelper(char c, Node n, int pos) {
if (n.next == null)
return n.item;
return pos += compare(n.item, positionHelper(c, n.next, pos));
}
private int compare(char c, int p) {
int result = 0;
if (c == p)
return result += 1;
return 0;
}
I understand why this isn't working; I'm returning a result of 1 and then comparing it to n.item when going back to the previous function call, which will never be true. What I don't know is how to make this work. Any guidance would be awesome.
You are using a singly-linked list, which means you can only traverse it in one direction, namely forward, i.e. from the first node to the last node.
The algorithm is then to traverse the list from first node to last node and compare each node's item with the item you are searching for. Also you need two variables that will hold the index in the list of both the last (i.e. ultimate) and the second last (i.e. penultimate) occurrences of the item you are searching for. Both these variables should have initial values of -1 (minus one).
When you hit the first occurrence of the searched for item, update the ultimate index variable. When you hit the next occurrence, set the penultimate index to the ultimate index and then update the ultimate index.
Repeat for every subsequent occurrence of the searched for item, i.e. set the penultimate index to the ultimate index and then set the ultimate index to the index of the current node in the list. Hence if the searched for item occurs only once in the list, or does not occur at all, the penultimate index will be -1.
When writing a recursive method, the first thing you need is some condition that will terminate the recursion. If the condition is true, return an appropriate value. If the condition is false, change the method arguments and recall the same method with the modified arguments. The terminating condition in your case is a null node.
Since a list is not an array, you also need to track the index of the current node, so as to be able to return it from your recursive method.
Here is my implementation. I created a LinkList class which contains a list of your Node class. The LinkList class allows me to initially create a linked list. I also added method toString() to both Node and LinkList classes to help visualize what the list looks like. The main() method serves as a test of the recursive method. The first invocation of the recursive method uses the first node in the list, whose index is 0 (zero).
public class Penultim {
public static void main(String[] args) {
LinkList list = new LinkList();
list.append('a');
list.append('b');
list.append('a');
list.append('b');
list.append('c');
list.append('d');
list.append('e');
list.append('f');
list.append('b');
System.out.println(list);
System.out.println(list.getPenultimateOccurrenceIndex('b', list.getHead(), 0, -1, -1));
}
}
class Node {
private char item;
private Node next;
public Node(char item, Node next) {
this.item = item;
this.next = next;
}
public char getItem() {
return item;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
public String toString() {
return item + "->";
}
}
class LinkList {
private Node head;
public void append(char item) {
if (head == null) {
head = new Node(item, null);
}
else if (head.getNext() == null) {
head.setNext(new Node(item, null));
}
else {
Node node = head.getNext();
while (node != null) {
if (node.getNext() == null) {
node.setNext(new Node(item, null));
break;
}
node = node.getNext();
}
}
}
public Node getHead() {
return head;
}
public int getPenultimateOccurrenceIndex(char item,
Node node,
int ndx,
int penultimate,
int ultimate) {
if (node == null) {
return penultimate;
}
else {
if (node.getItem() == item) {
if (ultimate >= 0) {
penultimate = ultimate;
}
ultimate = ndx;
}
return getPenultimateOccurrenceIndex(item,
node.getNext(),
ndx + 1,
penultimate,
ultimate);
}
}
public String toString() {
StringBuilder sb = new StringBuilder();
Node node = head;
while (node != null) {
sb.append(node);
node = node.getNext();
}
return sb.toString();
}
}
The output when running the above code is
a->b->a->b->c->d->e->f->b->
3
I’d do this in smaller steps. I’d start by writing a positionOfLastOccurrence(char letter). Writing this as a recursive method should teach you some of the technique that you will also need for positionOfSecondToLastOccurrence().
Next much of the challenge is in a good design of the helper method or methods. I think that I’d write a positionOfLastOccurrenceBeforePosition(int pos, char letter) that should return the position of the last occurrence of letter strictly before position pos. So given your example list, ababcdefb, positionOfLastOccurrenceBeforePosition(0, 'b') would return -1, positionOfLastOccurrenceBeforePosition(2, 'b') would yield 1 and positionOfLastOccurrenceBeforePosition(100, 'b') would give 8. This method too should be recursive, I believe, since this will the one doing the actual work in the end.
Now finding the second last occurrence is a matter of first finding the last occurrence and then finding the last occurrence before that one.
Problem: Given a value, remove all instances of that value from a linked list. More info below: JAVA
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
public ListNode removeElements(ListNode head, int val) {
ListNode n = head; //1, 2, 6, 3, 4, 5, 6
while(n.next == null){
if(n.next.val == val){
n.next = n.next.next;
}
n = n.next;
if(n == null){break;}
}
return head;
}
}
Since its a pass by reference, it should be updating shouldn't it?
I tried:
removeElements([1,2,6,3,4,5,6], 6)
But it didn't remove anything. So what I am doing incorrectly?
There are a couple of issues:
you want to loop until a node is null not until is not null (i.e. while( ... != null))
you might want to loop until n is null, not until n.next is null, otherwise you'd skip the last element
you want to check for n.val == val not n.next.val == val, otherwise you'd skip the first element
if you check n you want to keep track of the previous node in case you need to remove n, i.e. prev.next = n.next.
if the first element (the head) is to be removed you need to replace the head, i.e. return the second element (this can be done by checking prev == null which would mean that n is the current head).
As mentioned by Thomas in his first point, you wrote the while loop incorrectly. Also, because you have a single linked list, you need to keep track of the previous node (also mentioned by Thomas).
public static ListNode removeElements(ListNode head, int val)
{
ListNode n = head;
ListNode prev = null; //the previous node.
while (n != null)
{
if (n.value == val)
{
//if prev is null it means that we have to delete the head
//and therefore we need to advance the head
if (prev == null)
{
head = n.next;
prev = null;//remains at null because there's nothing before head
n = head;//new head, let's start from here
} else
{
prev.next = n.next; //let's skip the element to delete
n = n.next;//let's advance to the next node
}
} else
{
//nothing to delete, let's advance to the next node and make
//the current node the previous node in the next iteration
prev = n;
n = n.next;
}
}
return head;
}
Its always a good practice to solve these questions with proper test cases. Design the possible test cases including the corner cases. Then follow your algorithm and see if it solves the problem for the test cases. Write the code and dry run it, this will do a sanity check of the code as well as of the logic.
Below are the cases for this question for which test cases must be written.
Null list,
List with one element and value being equal to the value to be deleted
List with one element and value not being equal to the value to be deleted
List with two elements and first node value being equal to the value to be deleted
List with two elements and last node value being equal to the value to be deleted
List with three elements and first node value being equal to the value to be deleted
List with three elements and second node value being equal to the value to be deleted
List with three elements and last node value being equal to the value to be deleted
Below is the code for the problem of removing nodes with a given value in a linked list.
public ListNode removeElements(ListNode head, int val) {
while(head != null && head.val == val){
head = head.next;
}
if(head == null){
return null;
}
ListNode node = head;
while(node.next != null){
if(node.next.val == val){
node.next = node.next.next;
}else{
node = node.next;
}
}
return head;
}
I'm trying to reverse a list, but l want to keep my initial list. My function reverse doesn't keep the initial list
For example I want to reverse this:
Node n = new Node(1,new Node(12, new Node(34, new Node(3, Node.NIL))));
and my function is:
public Node reverse(){
Node p= this;
if(p == NIL)
return Node.NIL;
if(p.n == Node.NIL)
return p;
Node rest = p.getNext();
p.setNext(Node.NIL);
Node reverseRest = rest.reverse();
rest.setNext(p);
return reverseRest;
}
The length of my old list after the reverse is 1, and I want it to be 4 for this example. My old and my new list have to have the same length after the reverse.
In order to preserve the original list your reverse method must create new Nodes objects, rather than making modifications to existing ones.
If you would like to write a recursive reverse() that takes no parameters, you can do it as follows:
Make a new Node, and copy this node's content into it; set next to NIL
If the next of this node is NIL, return the result of previous step
Otherwise, call reverse() on the next
Take the return value from the previous call, and navigate to its end
Add the new node from step one to the end, and return the result.
A better approach is to change the signature of reverse to take the nodes created so far, in reverse order. This would produce an O(n) algorithm, while the unmodified algorithm above is O(n2).
This is a recursive implementation based on dasblinkenlight's (love the handle!) suggestion: "A better approach is to change the signature of reverse to take the nodes created so far, in reverse order"
public class Node {
private static final Node NIL=null;
public Node(int data, Node next) {
super();
this.data = data;
this.next = next;
}
public int getData() {
return data;
}
public Node getNext() {
return next;
}
private int data;
private Node next;
public String toString()
{
String s = "";
Node cur = this;
while (cur != Node.NIL) {
s += cur.data + ",";
cur = cur.getNext();
}
return s;
}
/* Where the recursive magic happens */
/* build the reversed list in the parameter 'reversed' */
public Node reverse(Node n, Node reversed)
{
if (n == Node.NIL) {
return reversed;
} else {
return reverse(n.next,new Node(n.data,reversed));
}
}
/* Kick off the recursion from the head node */
public Node reverseList() {
return reverse(this,Node.NIL);
}
public static void main (String args[]) {
// Create a sample list
Node n = new Node(1,new Node(12, new Node(34, new Node(3, Node.NIL))));
System.out.println(n);
System.out.println(n.reverseList());
}
}
I am trying to delete a node in the middle of two other nodes in a singly linked list.
public void deleteAfter(Node del){
del.next=del.next.next;
}
where it deletes the the node that is after the specified node,del.
I get a null pointer exception .I think the problem is after deletion the link with other nodes is broken.How can I mend it .Here's my full code :
public class Node{
public Object item;
public Node next;
public Node(){
item=null;
next=null;
}
public Node(Object x){
item=x;
next=null;
}
public void insertAfter(Node after,Object x){
Node newNode=new Node(x);
newNode.next=after.next;
after.next=newNode;
}
public void deleteAfter(Node del){//Deletes the node that is after the specified node
del.next=del.next.next;
}
public static void main (String args[]){
Node front=new Node(),p=new Node(),q=new Node();
p.item="green";
q.item="red";
p.next=q;
front=p;
front.deleteAfter(p);
front.insertAfter(p,"black");
front.insertAfter(q,"blue");
front.insertAfter(q.next,"orange");
front.deleteAfter(q);
System.out.println(front.item);
System.out.println(front.next.item);
System.out.println(front.next.next.item);
System.out.println(front.next.next.next.item);
}
}
First your list should remember last element or head.
public class YourList{
Node heaed;
public YourList(){
head = null;
}
public void insert(Node node){
if(last == null){
head = node;
}
}
public void deleteAfter(Node del){
if(del.next == head)){
head = del;
}
if(del.next == null){
//do nothing because there is nothing to delete
}
else{
del.next=del.next.next;
}
}
}
At:
p.next=q;
front=p;
front.deleteAfter(p);
front.insertAfter(p,"black");
You have created a two node linked list starting at p, and pointed front to it, then you shrank it down to a one node linked list, and bumped it back to two, consisting of { "green", "black" }. q is a singleton list node which you later manipulate.
When you print starting from front, since it only has two nodes, trying to obtain the item of the third node, which doesn't exist, causes your exception.
Your question started out by asking if there was something wrong with your deleteAfter(), and there is in that it won't correctly handle any correct list of nodes, only a list that actually has something after it. Passing in an empty list or a list with only one node in it will result in an exception.
You can first find the middle node using two pointer approach and then delete the node.
public Node findMiddleNode(Node node){
Node runner = node;
while(node!=null){
node = node.next;
if(node != null){
node = node.next;
runner = runner.next;
}
}
return runner;
}
public static boolean deleteNode(Node node){
if(node==null || node.next==null) return false;
Node next = node.next;
node.data = next.data;
node.next = next.next;
return true;
}
Solution which first calculates the size of the list and deletes the n/2 element without using two pointers.
For example, if given linked list is 1->2->3->4->5 then linked list should be modified to 1->2->4->5. If there are even nodes, then there would be two middle nodes, the second middle element gets deleted. For example, if given linked list is 1->2->3->4->5->6 then it should be modified to 1->2->3->5->6.
public void deleteMiddle() {
if (head == null) {
System.out.println("List is emplty");
return;
} else if (head.next == null) {
head = null;
return;
} else {
int count = 0;
int nodeDeleteIndex = 0;
Node node = this.head;
Node temp = this.head;
// To calculate the list size
while (node != null) {
count++;
node = node.next;
}
// getting the n/2 index of the node which needs to be deleted
nodeDeleteIndex = (count / 2);
for (int i = 0; i < nodeDeleteIndex - 1; i++) {
temp = temp.next;
}
temp.next = temp.next.next;
}
}
a linear linked list is a set of nodes. This is how a node is defined (to keep it easy we do not distinguish between node an list):
class Node{
Object data;
Node link;
public Node(Object pData, Node pLink){
this.data = pData;
this.link = pLink;
}
public String toString(){
if(this.link != null){
return this.data.toString() + this.link.toString();
}else{
return this.data.toString() ;
}
}
public void inc(){
this.data = new Integer((Integer)this.data + 1);
}
public void lappend(Node list){
Node child = this.link;
while(child != null){
child = child.link;
}
child.link = list;
}
public Node copy(){
if(this.link != null){
return new Node(new Integer((Integer)this.data), this.link.copy());
}else{
return new Node(new Integer((Integer)this.data), null);
}
}
public Node invert(){
Node child = this.link;
while(child != null){
child = child.link;
}
child.link = this;....
}
}
I am able to make a deep copy of the list. Now I want to invert the list so that the first node is the last and the last the first. The inverted list has to be a deep copy.
I started developing the invert function but I am not sure. Any Ideas?
Update: Maybe there is a recursive way since the linear linked list is a recursive data structure.
I would take the first element, iterate through the list until I get to a node that has no child and append the first element, I would repeat this for the second, third....
I sometimes ask this question in interviews...
I would not recommend using a recursive solution, or using a stack to solve this. There's no point in allocating O(n) memory for such a task.
Here's a simple O(1) solution (I didn't run it right now, so I apologize if it needs some correction).
Node reverse (Node current) {
Node prev = null;
while (current != null) {
Node nextNode = current.next;
current.next = prev;
prev = current;
current = nextNode;
}
return prev;
}
BTW: Does the lappend method works? It seems like it would always throw a NullReferenceException.
There's a great recursive solution to this problem based on the following observations:
The reverse of the empty list is the empty list.
The reverse of a singleton list is itself.
The reverse of a list of a node N followed by a list L is the reverse of the list L followed by the node N.
You can therefore implement the reverse function using pseudocode along these lines:
void reverseList(Node node) {
if (node == null) return; // Reverse of empty list is itself.
if (node.next == null) return; // Reverse of singleton list is itself.
reverseList(node.next); // Reverse the rest of the list
appendNodeToList(node, node.next); // Append the new value.
}
A naive implementation of this algorithm runs in O(n2), since each reversal requires an append, which requires an O(n) scan over the rest of the list. However, you can actually get this working in O(n) using a clever observation. Suppose that you have a linked list that looks like this:
n1 --> n2 --> [rest of the list]
If you reverse the list beginning at n2, then you end up with this setup:
n1 [reverse of rest of the list] --> n2
| ^
+------------------------------------------+
So you can append n1 to the reverse of the rest of the list by setting n1.next.next = n1, which changes n2, the new end of the reverse list, to point at n1:
[reverse of the rest of the list] --> n2 --> n1
And you're golden! Again more pseudocode:
void reverseList(Node node) {
if (node == null) return; // Reverse of empty list is itself.
if (node.next == null) return; // Reverse of singleton list is itself.
reverseList(node.next); // Reverse the rest of the list
node.next.next = node; // Append the new value.
}
EDIT: As Ran pointed out, this uses the call stack for its storage space and thus risks a stack overflow. If you want to use an explicit stack instead, you can do so like this:
void reverseList(Node node) {
/* Make a stack of the reverse of the nodes. */
Stack<Node> s = new Stack<Node>();
for (Node curr = node; node != null; node = node.next)
s.push(curr);
/* Start unwinding it. */
Node curr = null;
while (!s.empty()) {
Node top = s.pop();
/* If there is no node in the list yet, set it to the current node. */
if (curr == null)
curr = top;
/* Otherwise, have the current node point to this next node. */
else
curr.next = top;
/* Update the current pointer to be this new node. */
curr = top;
}
}
I believe that this similarly inverts the linked list elements.
I would treat the current list as a stack (here's my pseudo code):
Node x = copyOf(list.head);
x.link = null;
foreach(node in list){
Node temp = copyOf(list.head);
temp.link = x;
x = temp;
}
At the end x will be the head of the reversed list.
I more fammiliar whit C, but still let me try. ( I just do not sure if this runs in Java, but it should)
node n = (well first one)
node prev = NULL;
node t;
while(n != NULL)
{
t = n.next;
n.next = prev;
prev = n;
n = t;
}
Reversing a single-linked list is sort of a classic question. It's answered here as well (and well answered), it does not requires recursion nor extra memory, besides a register (or 2) for reference keeping.
However to the OP, I guess it's a school project/homework and some piece of advice, if you ever get to use single linked list for some real data storage, consider using a tail node as well. (as of now single linked lists are almost extinct, HashMap buckets comes to mind, though).
Unless you have to check all the nodes for some condition during 'add', tail is quite an improvement. Below there is some code that features the reverse method and a tail node.
package t1;
public class SList {
Node head = new Node();
Node tail = head;
private static class Node{
Node link;
int data;
}
void add(int i){
Node n = new Node();
n.data = i;
tail = tail.link =n;
}
void reverse(){
tail = head;
head = reverse(head);
tail.link = null;//former head still links back, so clear it
}
private static Node reverse(Node head){
for (Node n=head.link, link; n!=null; n=link){//essentially replace head w/ the next and relink
link = n.link;
n.link = head;
head = n;
}
return head;
}
void print(){
for (Node n=head; n!=null;n=n.link){
System.out.println(n.data);
}
}
public static void main(String[] args) {
SList l = new SList();
l.add(1);l.add(2);l.add(3);l.add(4);
l.print();
System.out.println("==");
l.reverse();
l.print();
}
}
I was wondering something like that(I didnt test it, so):
invert(){
m(firstNode, null);
}
m(Node v, Node bef){
if(v.link != null)
m(v.link,v);
else
v.link=bef;
}
Without much testing,
Node head = this;
Node middle = null;
Node trail = null;
while (head != null) {
trail = middle;
middle = head;
head = head.link;
middle.link = trail;
}
head = middle;
return head;
public ListNode Reverse(ListNode list)
{
if (list == null) return null;
if (list.next == null) return list;
ListNode secondElem = list.next;
ListNode reverseRest = Reverse(secondElem);
secondElem.Next = list;
return reverseRest;
}
Hope this helps.