There is a problem on leetcode called Odd Even Linked List.
It says:
Given a singly linked list, group all odd nodes together followed by the even nodes. Please note here we are talking about the node number and not the value in the nodes.
You should try to do it in place. The program should run in O(1) space complexity and O(nodes) time complexity.
Example:
Given 1->2->3->4->5->NULL,
return 1->3->5->2->4->NULL.
Here is my Node class
public class Node
{
private int value;
private Node next;
public Node(int Value)
{
this.value = Value;
this.next = null;
}
public Node()
{
this.value = -1;
this.next = null;
}
public Node getNext() {
return next;
}public void setNext(Node next) {
this.next = next;
}public int getValue() {
return value;
}public void setValue(int value) {
this.value = value;
}
}
I got 8 items in list which has values 1,2,3,4,5,6,7,8. This is my output -->1-->3-->5-->7-->2-->4-->6-->8
And here is my Linked list method to solve OddEven task.
public void oddEven()
{
if(head.getNext() == null)
return;
Node lastOdd = head.getNext(); // gets the value of last odd even in list.
Node current = lastOdd.getNext(); // Puts the reference on the first even index.
Node before = lastOdd; // This node, will always be one index before current Node
int travel = 1, loop;
while(current != null)
{
loop = travel;
// Prvo petlja putuje do sledeceg neparnog elementa
while(loop-- > 0)
{
before = current;
current = current.getNext();
}
if(current == null) // If it is end of the list, exit loop.
break;
before.setNext(current.getNext());
current.setNext(lastOdd.getNext());
lastOdd.setNext(current);
lastOdd = current;
current = before.getNext();
}
}
It works perfectly fine on my pc. But when i put code in leetcode i get the error that it doesnt work. But it is same code. Here is code from leetcode
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
public ListNode oddEvenList(ListNode head)
{
if(head.next == null)
return head;
ListNode lastOdd = head.next; // gets the value of last odd even in list.
ListNode current = lastOdd.next; // Puts the reference on the first even index
ListNode before = lastOdd;
int travel = 1, loop;
while(current != null)
{
loop = travel;
// Prvo petlja putuje do sledeceg neparnog elementa
while(loop-- > 0)
{
before = current;
current = current.next;
}
if(current == null)
break;
before.next = current.next;
current.next = lastOdd.next;
lastOdd.next = current;
lastOdd = current;
current = before.next;
}
return head;
}
}
Here is the error i get
for input :[1,2,3,4,5,6,7,8]
Your answer :[1,2,4,6,8,3,5,7]
Expected answer :[1,3,5,7,2,4,6,8]
But it is same method, where did i made mistake ?
I went to the site and put your code in to make it easier to see whats going on, the issue is this line:
ListNode lastOdd = head.next; // gets the value of last odd even in list.
The first element of the list is 1, yet you are starting the last odd as being the next in the list, not the head of the list. Just changing that to:
ListNode lastOdd = head
and it provides the correct answer.
The code itself needs some tidy up, the inner while loop seems to serve no real purpose, not sure why thats there or its a left over element of a previous attempt?
What loop and travel variables are doing? They are constant at 1 in each iteration, then why while(loop-- > 0) loop. Sorry didn't get what you are trying to achieve with that loop.
int travel = 1, loop;
while(current != null)
{
loop = travel;
// Prvo petlja putuje do sledeceg neparnog elementa
while(loop-- > 0)
{
Solution: Find the last node in the list. Move all even positioned nodes to the end, by doing append. Make sure you stop at the node marked as last in first step, else it would run into infinite loop.
Related
I'm on HackerRank and I need to remove duplicate items from a sorted linked list. I passed all the cases except for two of them which the input is something like: 10001102034
So my program takes to seconds to complete and exceed the time. How can I do my code more efficiently, I heard about using square root but I don't know how to use it. Any guide is appreciate. Here is my code.
private static Node removeDuplicates(Node head) {
/* Another reference to head */
Node current = head;
Node next;
/* Traverse list till the last node */
while (current != null && current.next != null) {
if (current.data == current.next.data) {
next = current.next.next;
if (next == null) {
current.next = null;
break;
}
current.next = next;
} else {
current = current.next;
}
}
return head;
}
Again. It works but takes too much times with longer numbers.
You should replace condition if (current.data == current.next.data) with while loop and use break 'label':
out:
while (current != null && current.next != null) {
while (current.data == current.next.data) {
next = current.next.next;
if (next == null) {
current.next = null;
break out;
}
current.next = next;
}
current = current.next;
}
You can't use the square root because when u want to remove duplicates from a list you have to check all the list .
The square root technique is used for searching in a sorted list.
But for your question if you can improve the runtime on that your code in O(n^2) but if you change your code to use hashtable you can make it O(n).
import java.util.HashSet;
public class removeDuplicates
{
static class node
{
int val;
node next;
public node(int val)
{
this.val = val;
}
}
/* Function to remove duplicates from a
unsorted linked list */
static void removeDuplicate(node head)
{
// Hash to store seen values
HashSet<Integer> hs = new HashSet<>();
/* Pick elements one by one */
node current = head;
node prev = null;
while (current != null)
{
int curval = current.val;
// If current value is seen before
if (hs.contains(curval)) {
prev.next = current.next;
} else {
hs.add(curval);
prev = current;
}
current = current.next;
}
}
/* Function to print nodes in a given linked list */
static void printList(node head)
{
while (head != null)
{
System.out.print(head.val + " ");
head = head.next;
}
}
I hope this will help you.
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.
So I am currently trying to create a circle linked list (double linked list with each value having a previous, and a next value not equal to null), and I am not sure if I am properly creating it. My goal is to be able to create a LinkedList of values, and then when I iterate through the list, hasNext() should always return true (no null values). I think there is something wrong with the way I am adding values, but I am not sure. Here is the code, with the CircularList class having an inner node class:
public class CircularList<E> {
//I decided to still have heads and tails, to link them together
private Node<E> first = null;
private Node<E> last = null;
private Node<E> temp;
private int size;
//inner node class
private static class Node<E>{ //In this case I am using String nodes
private E data; //matching the example in the book, this is the data of the node
private Node<E> next; //next value
private Node<E> prev; //previous value
//Node constructors, also since in this case this is a circular linked list there should be no null values for previous and next
private Node(E data, Node<E> next, Node<E> prev){
this.data = data;
this.next = next;
this.prev = prev;
}
}
//end of inner node class
public void addValue(E item){
Node<E> n = new Node<E>(item, first, last);
if(emptyList() == true){ //if the list is empty
//only one value in the list
first = n;
last = n;
}
else{ //if the list has at least one value already
temp = first;
first = n;
first.next = temp;
last.next = first;
}
size++;
}
public boolean emptyList(){
boolean result = false;
if(first == null && last == null){ //if there is no values at all
result = true;
}
return result;
}
}
Just did a quick scan but this is the bit where it goes wrong:
Node<E> n = new Node<E>(item, first, last);
if(emptyList() == true) {
//if the list is empty
//only one value in the list
first = n;
last = n;
}
The prev and next item inside node are still null here. You should set those too.
else {
//if the list has at least one value already
temp = first;
first = n;
first.next = temp;
last.next = first;
}
Additionally you're not updating prev here.
Also consider using a linked list internally as a backing data structure rather then your own node structure. Then you only have to create the circular iterator.
I'm working on a linked-list program, which allows me to loop over the list only once, and I can't copy the elements of the list to another data structure.
Suppose that the list is not empty (has at least one node) and the next of the last node is null.
The following method return the element at the index (2n/3) of a list of length n.
for example if n=1 or n=2 it returns the first element
if n=3 or n=4 it returns the second element.
I thought of keeping a temporary node that gets the next node if the number (2n/3) is an integer.
Is there a better way to do this?
public class LinkedListNode {
private int value;
private LinkedListNode next;
public LinkedListNode(int value) {
this.value = value;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public LinkedListNode getNext() {
return next;
}
public void setNext(LinkedListNode next) {
this.next = next;
}
}
public class ListUtils {
public static LinkedListNode findTwoThirdsNode(LinkedListNode head){
int length=0;
LinkedListNode node=head.getNext();
LinkedListNode tmp=head;
double divresult=1;
while (node!=null){
length++;
divresult=(2*length)/3;
node=node.getNext();
if (divresult%1==0){
tmp=tmp.getNext();
}
}
if (length==1 || length==2){
return head;
}
else
return tmp;
}
}
You can do this by running over the linked list twice, but interleaved (in other words without a reset). You simply use a rabbit-and-tortoise-approach: you have the rabbit that hops three times per iteration, and the tortoise which hops twice each time:
LinkedListNode rabbit = head;
LinkedListNode tortoise = head;
while(rabbit != null) { //repeat until the rabit reaches the end of the list
for(int i = 0; rabbit != null && i < 2; i++) {
rabbit=rabbit.getNext(); //let the rabbit hop the first and second time
if(rabbit != null) {
tortoise=tortoise.getNext(); //let the tortoise hop the first and second time
}
}
if(rabbit != null) {
rabbit=rabbit.getNext(); //let the rabbit hop a third time
}
}
return tortoise; //if reached the end, we return where the tortoise ended
If you want the result to be as close as possible to 2/3rd (so not with much rounding errors), you better interleave the rabbit and tortoise hops as is done in the for loop. Furthermore you must do null checkings each time since it is possible that the length is not modulo three.
Keep 2 pointers, when you go thru the loop progress the left of them only 2/3 of the time.
when you reach the end of the loop return the pointer to the other node.
int i = 0;
node temp = head;
node progress = head;
while(progress != null) {
i++;
progress = progress.next;
if(i == 2 && progress != null) temp = temp.next;
else if ( i == 3 && progress != null) {
temp=temp.next;
i=0;
}
}
return temp;
}
this is the general idea
What about a simple for loop?
int n = // ...
int index = 2 * n / 3;
LinkedListNode current = head;
for(int i = 0 ; i < index ; ++i) {
current = current.next();
}
return current;
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.