I am trying to reverse a subpart of a singly-linked list where the subpart is a contiguous set of even elements, bordered by either the end of the list or an odd element.
So far, I know how to reverse a linked list but I'm unable to figure out how to check if the element is odd or if it's at the end.
Node reverse(Node head) {
// Write your code here
if(head == null) return null;
Node prev = null;
Node curr = head;
Node next = null;
while(curr != null) {
next = curr.next;
curr.next = prev;
prev = curr;
curr = next;
}
return prev;
}
Example
Input:
list = [1, 2, 8, 9, 12, 16]
Output:
[1, 8, 2, 9, 16, 12]
The subparts in this example are 2,8 and 12,16
Node reverse(Node head) {
if(head == null) return null;
Node curr = head;
Node next = null;
Node prev = null;
while(curr!=null && curr.data%2==0) {
next = curr.next;
curr.next = prev;
prev = curr;
curr = next;
}
if(curr!=head) {
head.next = curr;
curr = reverse(curr);
return prev;
} else {
head.next = reverse(head.next);
return head;
}
}
Q. Given a singly linked list of integers, reverse every contiguous set of nodes that have only even values.
I/P = 1 2 3 3 4 6 8 5, O/P = 1 2 3 3 8 6 4 5, explanation -
There are two sub lists of even elements, which [2] and [4->6->8]. The sub list [4->6->8] has been reversed and the single sub list [2] need not be reversed.
Test Cases passed
1 3 8 3 4 2 6 5 single/multi even element in list,
2 4 6 1 3 even occurs at head,
1 4 4 6 8 even occurs till tail,
2 4 6 8 2 all even in the list
import java.util.*;
//import ds.List.ListNode; import your ListNode class
/*
public class ListNode {
public int val;
public ListNode next;
public ListNode(int x) { val = x; next = null; }
}
*/
class Solution{
public ListNode reverseEvenElements(ListNode head)
{
ListNode p = null;//prev
ListNode c = head;//curr
while(c != null){
if(c.val % 2 == 0){
ListNode start = p;
while(c != null && c.val % 2 == 0){
p = c;
c = c.next;
}
//end of even elements = p
//making end of even node to null so that reverse should stop
//otherwise it will reverse whole list
p.next = null;
ListNode[] node;// [head,tail]
// if start is null i.e. even element found at head itself
if(start == null){
node = reverseList(head);
head = node[0];//node[0] = head of reversed list
}else{// start != null
node = reverseList(start.next);
start.next = node[0];
}
node[1].next = c;//node[1] = tail of reversed list
}
if(c != null){
p = c;
c = c.next;
}
}
return head;
}
// this method will be called when even elements occurs till last even element we get
//in the original list returns head & tail of reversed list
public static ListNode[] reverseList(ListNode head){
ListNode p = null;
ListNode c = head;
ListNode n = head.next;
while(true){
c.next = p;
p = c;
c = n;
if(n == null)
break;
else
n = n.next;
}
return new ListNode[] {p, head};// [head,tail]
}
}
from what you given me i understood like :
input : [1,2,4,8,5,7,7,6,6,2,8,1,1,1,2,4]
output: [1,8,4,2,5,7,7,8,2,6,6,1,1,1,4,2]
i have edited your code for reverse to reverse till which will reverse intervals & created reverse_whole which will find those intervals
public ListNode reverse_whole(ListNode head) {
ListNode temp=head;
ListNode pre_temp=new ListNode(0,temp);
ListNode ans_pre = pre_temp;
while(temp!=null){
if(temp.val%2==0){
ListNode temp_till=temp;
while(temp_till!=null&& temp_till.val%2==0){
temp_till=temp_till.next;
}
// temp_till will iterate over even number interval after one
//so: 1,2,4,6,7 : 7 is temp_till
// reverse 2,4,6 so it become : 1,6,4,2,7
pre_temp.next=reverse_subpart(temp,temp_till);
temp=temp_till;
}
pre_temp=temp;
if(temp!=null)temp=temp.next;
}
return ans_pre.next;
}
public ListNode reverse_subpart(ListNode head,ListNode end) {
// Write your code here
if(head == null) return null;
ListNode prev = null;
ListNode curr = head;
ListNode next = null;
while(curr != end) {
next = curr.next;
curr.next = prev;
prev = curr;
curr = next;
}
head.next=end;
return prev;
}
run reverse_whole
if you have any doubt can write me
class LinkedList {
Node head;
Node curr = head;
Node next = null;
Node prev = null;
class Node {
int data;
Node next;
Node(int d)
{
data = d;
next = null;
}
}
void pairWiseSwap()
{
Node temp = head;
while (temp != null && temp.next!=null) {
int k = temp.data;
int j = temp.next.data;
if(k%2==0 && j%2==0) {
temp.data=j;
temp.next.data=k;
temp=temp.next.next;
continue;
}
temp = temp.next;
}
}
public void push(int new_data)
{
Node new_node = new Node(new_data);
new_node.next = head;
head = new_node;
}
void printList()
{
Node temp = head;
while (temp != null) {
System.out.print(temp.data + " ");
temp = temp.next;
}
System.out.println();
}
public static void main(String args[])
{
LinkedList llist = new LinkedList();
llist.push(16);
llist.push(12);
llist.push(9);
llist.push(8);
llist.push(2);
llist.push(1);
System.out.println("Linked List before calling pairWiseSwap() ");
llist.printList();
llist.pairWiseSwap();
System.out.println("Linked List after calling pairWiseSwap() ");
llist.printList();
}
}
Related
The following code is my attempt at implementing SinglyLinkedListNode and SinglyLinkedList classes and use the SinglyLinkedListNode reverse(SinglyLinkedListNode head) method to reverse this linked list.
The input consists of the first line detailing the number of test cases, t. And for each test case, the first line, n, represents the number of elements in the linked list. The next n number of lines will each contain an element from this list such that the input is as follows:
1 (number of test cases)
5 (number of elements in list)
1 (element in list)
2 (element in list)
3 (element in list)
4 (element in list)
5 (element in list)
How can I fix the following code so that it can print this reversed linked list, such that the output would be as follows:
5 4 3 2 1
As my code instead prints out the following:
1
5
1
2
3
4
5
1 2 3 4 5
My code:
import java.util.Scanner;
public class ReverseLinkedList {
static class SinglyLinkedListNode {
public int data;
public SinglyLinkedListNode next;
public SinglyLinkedListNode(int nodeData) {
data = nodeData;
next = null;
}
}
static class SinglyLinkedList {
private SinglyLinkedListNode head;
private SinglyLinkedListNode tail;
public SinglyLinkedList() {
SinglyLinkedListNode head = null;
SinglyLinkedListNode tail = null;
}
public void insertNode(int nodeData) {
SinglyLinkedListNode node = new SinglyLinkedListNode(nodeData);
if (this.head == null) {
this.head = node;
} else {
this.tail.next = node;
}
this.tail = node;
}
public SinglyLinkedListNode reverse(SinglyLinkedListNode head) {
SinglyLinkedListNode previous = null;
SinglyLinkedListNode current = head;
SinglyLinkedListNode next = null;
while (current != null) {
next = current.next;
current.next = previous;
previous = current;
current = next;
}
return previous;
}
public void printLinkedList() {
SinglyLinkedListNode node = head;
while (node != null) {
System.out.print(node.data + " ");
node = node.next;
}
}
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
SinglyLinkedList list = new SinglyLinkedList();
int testCases = input.nextInt();
if (testCases <= 10) {
input.nextLine();
int size = input.nextInt();
if (size <= 1000) {
for (int i = 0; i < size; i++) {
list.insertNode(input.nextInt());
}
list.reverse(list.tail);
list.printLinkedList();
}
}
}
}
use list.reverse(list.head)
and modify your reverse method as
SinglyLinkedListNode previous = null;
SinglyLinkedListNode current = head;
SinglyLinkedListNode next = null;
while (current != null) {
next = current.next;
current.next = previous;
previous = current;
current = next;
}
head= previous;
return head;
Also in your method printLinkedList set
SinglyLinkedListNode node = tail; // instead of head
You should pass head of the linkedlist instead of tail to reverse method.
list.reverse(list.head);
// Complete the sortedInsert function below.
/*
* For your reference:
*
* DoublyLinkedListNode {
* int data;
* DoublyLinkedListNode next;
* DoublyLinkedListNode prev;
* }
*
*/
static DoublyLinkedListNode sortedInsert(DoublyLinkedListNode head, int data) {
DoublyLinkedListNode Leader=head;
DoublyLinkedListNode newNode = new DoublyLinkedListNode(data);
while(Leader.next!=null){
if(data>Leader.data){
Leader = Leader.next;
}
else {
if(Leader.prev == null) {
newNode.next = Leader;
Leader.prev = newNode;
head = newNode;
return head;
}
}
}
if(Leader.next == null) {
if(data<Leader.data) {
newNode.prev = Leader.prev;
newNode.next = Leader;
Leader.prev.next = newNode;
return head;
} else {
newNode.prev = Leader;
Leader.next = newNode;
return head;
}
}
return head;
}
in the above-sorted insert method how to decrease this doubly linked list complexity, this is a hackerrank question I'm getting timed outs for the test cases I need help in decreasing the time complexity for this code.
You code will never come out of while loop.
Lets take the example. List = [(1), (4), (4)](only 1 element). New node is (4). Your result should be [(1), (4), (4), (4)]. But lets walk your code and check what will happen. Initially Leader = (1)
while(Leader.next!=null){ // 1
if(data>Leader.data){ // 3
Leader = Leader.next;
}
else { // 6
if(Leader.prev == null) { // 7
newNode.next = Leader;
Leader.prev = newNode;
head = newNode;
return head;
}
}
}
At line 1 check will pass (as (1).next is not null; in fact it is (4)).
At line 3 ((4) > (1)). Check pass. Leader = (1).next = (4). Jump to line 1
At line 1 check will pass (as (4).next is not null; in fact it is (4)).
At line 3 ((4) > (4)). Check Fail. Enter line 7
At line 7 check will fail ((4).prev is not null; in fact it is (4) - 1st 4). No update in Leader will take place. Leader will remain same & you will enter infinte loop from here.
You will have to take care of this. Maybe the Problem's discussion page will help. But do give it a through try.
My own try is included below:
static DoublyLinkedListNode sortedInsert(DoublyLinkedListNode head, int data) {
DoublyLinkedListNode n = new DoublyLinkedListNode();
n.data = data;
DoublyLinkedListNode curr = head;
if (head == null) {
return n;
}
// if given node is smaller than 1st node
if (data < curr.data) {
n.next = curr;
return n;
}
// find first node greater than given node
while (curr.next != null && curr.data < data) {
curr = curr.next;
}
// reached to the end.
if (curr.next == null && data >= curr.data) {
curr.next = n;
} else { // found the 1st node which is greater than given node
curr.prev.next = n;
n.next = curr;
}
return head;
}
I'm trying a standard interview question, which is to add two digits in the form of linkedlists and return the added answer. Here is the question:
You are given two linked lists representing two non-negative numbers.
The digits are stored in reverse order and each of their nodes contain
a single digit. Add the two numbers and return it as a linked list.
Input: (2 -> 4 -> 3) + (5 -> 6 -> 4) Output: 7 -> 0 -> 8
342 + 465 = 807 Make sure there are no trailing zeros in the output list So, 7 -> 0 -> 8 -> 0 is not a valid response even though
the value is still 807.
Now, the code I am writing takes in two arguments in the form of ListNode datatypes which is the starting node of the LinkedLists. What I am not understanding is
How do I maintain the head node of the list to reference later?
How does call by value and call by reference work in Java? I've dealt with pointers and call by reference in C++ but I've been trying stuff in Java now and it's pretty different.
class ListNode {
public int val;
public ListNode next;
ListNode(int x) {
val = x;
next = null;
}
}
public class Solution {
public ListNode reverse(ListNode head) {
ListNode curr = head;
ListNode next = null;
ListNode prev = null;
while (curr != null) {
next = curr.next;
curr.next = prev;
prev = curr;
curr = next;
}
head = prev;
return head;
}
public ListNode addTwoNumbers(ListNode a, ListNode b) {
ListNode node = null;
ListNode head = null;
boolean carry = false;
while (a != null || b != null) {
int f = 0, s = 0;
if (carry) {
f++;
}
carry = false;
if (a != null) {
f += a.val;
a = a.next;
}
if (b != null) {
s = b.val;
b = b.next;
}
if (f + s > 9) {
carry = true;
}
int curr = (f + s) % 10;
node = new ListNode(curr);
if (head == null) {
head = node;
}
node = node.next; //warning that 'value of node assigned is never used'
}
if (carry) {
node = new ListNode(1);
}
printList(head);
return node;
}
}
node plays an ambiguous role.
node = new ListNode(curr);
node = node.next; // assigns null
Rename node into previous and do:
int curr = (f + s) % 10;
ListNode newNode = new ListNode(curr);
if (head == null) { // Or `previous == null`
head = newNode;
} else {
previous.next = newNode;
}
previous = newNode;
...
return head;
The technique to handle head is to make it a private field of a container class LinkedList.
As in java the parameter passing is call-by-value: f(a) never changes the variable a: the slot where the object pointer / value is stored. Instead to object pointer / value is pushed on the stack. (The object value may have its fields changed.)
So a recursive insert might look like head = insert(head, ...).
In C on can use aliasing, not only for parameter passing:
ListNode* head = NULL;
ListNode** node = &head;
shile (...) {
...
*node = newNode;
node = &(newNode->next);
}
Why so complicated?
public class Solution {
public ListNode addTwoNumbers(ListNode a, ListNode b) {
int firstNumber = nodeToNumber(a);
int secondNumber = nodeToNumber(b);
return numberToNode(firstNumber + secondNumber);
}
public int nodeToNumber(ListNode node) {
if (node.next != null) return node.value + 10 * nodeToNumber(node.next);
return node.value;
}
public ListNode numberToNode(int number) {
ListNode result = new ListNode(number % 10);
if (number > 10) result.next = numberToNode(number / 10);
return result;
}
}
Here is my singly linked list code:
public class SinglyLinkedList {
private static Node head;
private static int listSize;
private static class Node {
int value;
Node next;
Node(int i) {
value = i;
next = null;
}
}
public static void main(String[] args) {
head = null;
listSize = 0;
for (int i = 0; i < 10; i++) {
Node n = new Node(i);
if (head == null) {
head = n;
} else {
getLastNode(head).next = n;
}
listSize++;
}
printNodeValues(head);
Node revHead = reverseList(head);
printNodeValues(revHead);
}
private static Node reverseList(Node head) {
Node reverseHead = getLastNode(head);
Node reference = reverseHead;
while (listSize>0){
Node temp = getPreviousNode(reference, head);
Node last = getLastNode(reverseHead);
temp.next = null;
last.next = temp;
reference = temp;
listSize--;
}
return reverseHead;
}
private static Node getPreviousNode(Node reference, Node head) {
Node temp = head;
while (temp != null) {
if (temp.next == reference) {
break;
} else {
temp = temp.next;
}
}
return temp;
}
private static Node getLastNode(Node n) {
Node temp = n;
while (temp != null) {
if (temp.next == null) {
break;
} else {
temp = temp.next;
}
}
return temp;
}
public static void printNodeValues(Node h) {
while (h != null) {
System.out.print(h.value + " ");
h = h.next;
}
System.out.println();
}
}
The problem is with my reverseList(Node) method. When I run the program, I get the following error:
Exception in thread "main" java.lang.NullPointerException
at SinglyLinkedList.reverseList(SinglyLinkedList.java:44) -> temp = null;
at SinglyLinkedList.main(SinglyLinkedList.java:33) -> Node revHead = reverseList(head);
My printNodeValues works fine, and prints
0 1 2 3 4 5 6 7 8 9
and I'm trying to use reverseList to print
9 8 7 6 5 4 3 2 1 0.
There are many very bad things in your code. Worst of all : why is everything static ? What's the point of writing a list class that can be instantiated only once ?
Then, the size of the list should never be affected by a reverse operation, and you don't even need a counter since you just have to iterate over the list until you find a node which has no successor.
private static Node reverseList(Node head) {
Node res = null;
while (head != null) {
Node node = new Node(head.value);
node.next = res;
res = node;
head = head.next;
}
return res;
}
Your reverseList() method needs to skip the iteration when it has reached the first node in the original list because it's previous node doesn't exist. This first node has already be assigned as the next node (i.e. the last node in the reversed list) in the second last iteration (of your original loop).
private static Node reverseList(Node head) {
Node reverseHead = getLastNode(head);
Node reference = reverseHead;
int counter = listSize;
while ( counter > 1) {
Node temp = getPreviousNode(reference, head);
Node last = getLastNode(reverseHead);
temp.next = null;
last.next = temp;
reference = temp;
counter--;
}
return reverseHead;
}
Secondly, you shouldn't modify your listSize variable directly because the number of elements in the reversed list remains the same. Here, I'm storing it in a temporary counter first before iterating the list.
And, finally the reversed list should become your current head. Since, you've modified the linking between all the elements, it can only be traversed if your head now points to the new head.
printNodeValues(head);
head = reverseList(head);
printNodeValues(head);
I have written a code to swap elements of linkedList in Java.
Currently, my code fails, i.e., it is not swapping elements. I am having difficulty
on how to approach to this problem. Any tips?
public void switchPairs(){
if (front==null || front.next==null)
return ;
ListNode temp=front;
front=front.next;
ListNode curr=front;
while(curr.next!=null){
ListNode dummy = curr.next;
curr.next=temp;
temp.next=dummy;
temp=temp.next;
curr=dummy;
}
}
Input : front -> [3] -> [7] -> [4] -> [9] -> [8] -> [12] /
Expected output: front -> [7] -> [3] -> [9] -> [4] -> [12] -> [8] /
my output: front -> [7] -> [3] -> [4] -> [9] -> [8] -> [12] /
The way I approach this problem is
Draw the linkedList for the input and desired output in the right format for the simplest case. Here I would start with 4 nodes;
Then tackle the easy cases such as if the ListNode or the next is null
On the paper, mark the links that are broken and that are formed. Note you have to do the breaking and linking in right order; Make sure you have reference to the nodes whose link you are breaking. otherwise you might end up losing some nodes. That is the whole crux here. Draw after each step when a node is broken or a link is formed. In this way, you can keep track of what is going;
Translate what you have drawn on paper to code. That must be fairly straightforward!
Often you would need to have temporary pointers to traverse the list;
In this example, the front or head pointer needs to be changed. so I would do the first swap outside an iteration. The remaining changes I would inside a while loop.
write a convienient toString method that can help you track the variables at each stage. I found it harder to use debuggers forrecusions and linkedLists. but that is just me.
Regarding the solution for this problem: This is not as easy problem in my opinion. but a good one to get a good grasp of linkedLists andPointers`
here is my solution:
public void switchPairs(){
if (front==null || front.next==null)
return ;
//keep a pointer to next element of front
ListNode current=front.next;
//make front point to next element
front.next=current.next;
current.next=front;
front=current;
//current has moved one step back it points to first.
//so get it to the finished swap position
current=current.next;
while(current.next!=null && current.next.next!=null){
ListNode temp = current.next.next;
current.next.next=temp.next;
temp.next=current.next;
current.next=temp;
current=temp.next;
}
}
The best way to answer a question like this to to visualize the state of your list as it progresses thru the iteration. I have implemented the code with a println to help with that. The other choice is to include variable names that are easier to keep track of, while temp and dummy will not prevent you from achieving correctness they are more difficult to follow.
This is the function
public ListNode switchPairs(){
if (this==null || this.next==null)
return this;
ListNode top = this.next;
ListNode first = this;
ListNode second = first.next;
do {
ListNode third = second.next;
second.next = first;
first.next = third;
first = third;
System.out.println("### " + top.toString());
if (first != null) {
// remember second now is really the first element on the list
// at this point.
second.next.next = first.next;
second = first.next;
}
} while(first != null && second != null);
return top;
}
And this is the entire code
public class ListNode {
private ListNode next = null;
private final int i;
ListNode(int i) {
this.i = i;
}
ListNode(int i, ListNode parent) {
this(i);
parent.next = this;
}
#Override
public String toString() {
StringBuilder sb = new StringBuilder("[" + this.i + "]");
if (this.next != null) {
sb.append("->");
sb.append(this.next.toString());
}
return sb.toString();
}
public static void main(String[] args) {
ListNode top = null;
ListNode curr = null;
for(String arg : args) {
int i = Integer.parseInt(arg);
if(curr == null)
curr = new ListNode(i);
else
curr = new ListNode(i, curr);
if( top == null)
top = curr;
}
System.out.println(top.toString());
top = top.switchPairs();
System.out.println(top.toString());
}
public ListNode switchPairs(){
if (this==null || this.next==null)
return this;
ListNode top = this.next;
ListNode first = this;
ListNode second = first.next;
do {
ListNode third = second.next;
second.next = first;
first.next = third;
first = third;
System.out.println("### " + this.toString());
if (first != null) {
second.next.next = first.next;
second = first.next;
}
} while(first != null && second != null);
return top;
}
}
Last but not least a sample output
java ListNode 1 2 3 4 5 6 7 8
[1]->[2]->[3]->[4]->[5]->[6]->[7]->[8]
### [2]->[1]->[3]->[4]->[5]->[6]->[7]->[8]
### [2]->[1]->[4]->[3]->[5]->[6]->[7]->[8]
### [2]->[1]->[4]->[3]->[6]->[5]->[7]->[8]
### [2]->[1]->[4]->[3]->[6]->[5]->[8]->[7]
[2]->[1]->[4]->[3]->[6]->[5]->[8]->[7]
public void switchPairs() {
ListNode prev = front;
if(front!=null && front.next != null) {
ListNode temp = front;
front = front.next;
temp.next = front.next;
front.next = temp;
prev = temp;
}
while(prev !=null && prev.next != null && prev.next.next != null) {
ListNode first_node =prev.next;
ListNode second_node = first_node.next;
first_node.next = second_node.next;
second_node.next = first_node;
prev.next = second_node;
prev = first_node;
}
}
// Recursive solution
public void switchPairs(SingleLinkListNode prev, SingleLinkListNode node) {
if (node == null || node.next == null) {
return;
}
SingleLinkListNode nextNode = node.next;
SingleLinkListNode temp = nextNode.next;
nextNode.next = node;
node.next = temp;
if (prev != null) {
prev.next = nextNode;
} else {
head = nextNode;
}
switchPairs(node, node.next);
}
I have this recursive function, which works:
public void swap2List(){
root = swap2List(root); //pass the root node
}
private Node swap2List(Node current){
if(current == null || current.next == null){
return current;
}
else{
Node temp = current;
Node temp2 = current.next.next;
current = current.next;
current.next = temp;
temp.next = swap2List(temp2);
}
return current;
}
public static LinkedList<Integer> switchPairs(LinkedList list) {
ListIterator<Integer> iterator = list.listIterator();
LinkedList<Integer> out = null;
while (iterator != null && iterator.hasNext()) {
if (out == null) {
out = new LinkedList<Integer>();
}
int temp = iterator.next();
if (iterator.hasNext()) {
out.add(iterator.next());
out.add(temp);
}else{
out.add(temp);
}
}
return out;
}