LinkedList sum function deletes the entire list once finished? - java

This is for practice purposes not a real world problem.
I am summing all the nodes of int data type in a linked list this works fine.
I am also summing all the nodes with even numbers of int data type in a linked list this works fine.
But when I call one after the other in the test class the entire list is empty(Well set to null).
I think it is to do with this line head = head.next;
data() returns the data stored on that node
TEST Class
linkedList.addTail(4);
linkedList.addTail(7);
linkedList.addTail(2);
linkedList.addTail(7);
linkedList.sum();
//The list is empty here
linkedList.sumEven();
Linked List
public int sum(){
int sum = 0;
while (head != null) {
sum += head.data;
//Here
head = head.next;
}
System.out.println(sum);
return sum;
}
public int sumEven(){
//To keep track of the sum
int sum = 0;
while (head != null)
{
//If the data at head is even add
if (head.data() % 2 == 0)
sum += head.data;
//Or Here
head = head.next;
}
System.out.println(sum);
return sum;
}

You are overriding head every time you assign it. You can either make a copy of it before summing or sum using a for like similar to the following.
for(Integer i: head) sum += i;
I have assumed that the elements in your LinkedList are of type int.

Related

Finding the 'maximum' character in a linked list Java recursively

I am trying to find the "maximum" value in a linked list recursively using a helper function. I am just starting to learn about these in my class and am pretty confused. We have a custom class that defines the type Node and another function to calculate the size of the Node or linkedlist. I solved this problem when I was comparing integers, but with characters I am lost. Here is my code:
'''
static class Node {
public Node (char item, Node next) { this.item = item; this.next = next; }
public char item;
public Node next;
}
Node first; // this is the only instance variable,
// the access point to the list
// size
//
// a function to compute the size of the list, using a loop
// an empty list has size 0
public int size () {
int count = 0;
for (Node tmp = first; tmp != null; tmp = tmp.next)
count++;
return count;
}
/*
* maxCharacter
*
* a function to compute the 'maximum' character in the list using recursion
* You will want to create a helper function to
* do the recursion
*
* precondition: list is not empty
*
* Examples:
* ["ababcdefb"].maxCharacter() == 'f'
* ["eezzg"].maxCharacter() == 'z'
* ["a"].maxCharacter() == 'a'
*/
public char maxCharacter () {
return maxCharacterHelper(first, first.size());
}
public char maxCharacterHelper(Node first, int index) {
char[] alpha = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
int max = 0;
while(index > 0 )
max = alpha.indexOf(first.item) > max ? first.item : max;
maxCharacterHelper(first, index-1);
return max;
}
'''
If you could explain how I would loop through the list recursively while maintaining the greatest char I would greatly appreciate it.
The golden rule with recursion is "Think of the base case first, then write the recurrence".
In this case, the base is the empty list. In this case, the maximum is the last value you've seen.
The recurrence is just a call to the rest of the list with the highest value you've called.
public static MaxNode(Node n, char currentMax) {
if (n == null) // base case, we're at the end.
return currentMax;
// recurrence
return MaxNode(n.next, currentMax > n.item ? currentMax : n.item);
}
For simple ASCII values, you can treat the maximum using the > operator.
Your while loop is confusing because of indentation and because you never change index. However, I don't think you need it if your intent is to use recursion. Generally with recursion you need to establish a base case from which you cannot recurse. For a linked list the natural base case is where there is no next node, rather than index-based.
if (current.next == null)
return alpha.indexOf(current.item);
Otherwise combine the recursion return with the current value
int remainingMax = maxCharacterHelper(current);
int currentValue = alpha.indexOf(current.item);
return (remainingMax > currentValue) ? remainingMax : currentValue;
Here is how I would put it together
//I made it static because it is not a method of a specific Node
public static int maxCharacterHelper(Node currentNode){
// remaining list includes only current node, so this one has max value
if (current.next == null)
return alpha.indexOf(current.item);
//otherwise take the larger of remaining list and current node
int remainingMax = maxCharacterHelper(current.next);
int currentValue = alpha.indexOf(current.item);
return (remainingMax > currentValue) ? remainingMax : currentValue;
}

Counting inversions in a linked-list with O(n log n) running time

I've created a very simple linked list in Java:
public class LinkedList {
class Node {
public Node next;
public int item;
public Node (int item) {
this.item = item;
}
}
int listSize = 0;
Node first = null;
Node last = null;
public void add(int n) {
Node node = new Node(n);
if (first == null) {
first = node;
} else {
last.next = node;
}
last = node;
listSize++;
}
}
So in the main class, I'll be adding elements to the linked list in a random order. But how can I create a method that counts the number of inversions in the linked-list?
So far, I've managed to achieve it with O(N^2) running time:
public int inversionCount() {
int count = 0;
Node current = this.first;
for (int i = 0; i <= this.listSize - 2; i++) {
Node next = current.next;
for (int j = i + 1; j < this.listSize; j++) {
if (current.item > next.item) {
System.out.print("(" + current.item + "," + next.item + ")" + " ");
count += 1;
}
next = next.next;
}
current = current.next;
}
return count;
}
However, as I said, the running time for this algorithm is O(N^2). I'm trying to achieve a running time of O(NlogN). How can this be achieved?
You are using bubble sort which has complexity of O(n^2)
For linked list the algorithm which is applicable with complexity of O(n log n) is Merge Sort.
Please see this walk trough of merge sort for linked lists
In insertion sort it would take o(n) on a normal array as even if you use binary search to find where the element needs to be sorted it would take o(n) to make new space for the array. In a linked list, it takes o(1) to insert and with binary search, you can get a complexity of o(nlogn). From there you can count the inversions of this array by counting the calculation of the index to move minus the previous index. Add all of these calculations up every time to get the number inversions.

LinkedList function from InterviewBit

I'm struggling with my solution for a question on InterviewBit.
I linked to the full description, but in short:
1) You are given the head node of a linkedlist
2) take the first half of the list and change the values so that:
"1st node’s new value = the last node’s value - first node’s current value
2nd node’s new value = the second last node’s value - 2nd node’s current value"
Here is my approach (it compiles but does not mutate the list at all)
I see that my method does not actually modify the original list -- it seems like what I'm doing is making a new list with the correctly altered values, but not changing the original.
/**
* Definition for singly-linked list.
* class ListNode {
* public int val;
* public ListNode next;
* ListNode(int x) { val = x; next = null; }
* }
*/
public class Solution {
public ListNode subtract(ListNode a) {
ListNode current = a;
int length = 0;
//get length
while(current.next != null){
length++;
current = current.next;
}
length += 1;
while(current.next != null){
double half = Math.floor(length/2);
for(int i=0; i<half; i++ ){
//
// if(i == 0){
// int aval = (nthToLast(a, length)).val - a.val;
// a.val = ((nthToLast(a, length-i)).val - a.val);
// a.next = current;
// }
current.val = ((nthToLast(a, length-i)).val - current.val);
current = current.next;
}
}
return a;
}
/* Helper function that given LinkedList head, and int n,
returns the nth to last ListNode in the LinkedList */
public ListNode nthToLast(ListNode head, int n){
ListNode nth = head;
ListNode ahead = head;
/* strategy: set nth to head, and 'ahead' to n places in front of 'nth'
increment at same speed and then when 'ahead' reaches the end, 'nth'
will be in the nth place from the end.
*/
while(ahead.next != null){
for(int i=0; i<n; i++){
ahead = ahead.next;
}
nth = nth.next;
ahead = ahead.next;
}
return nth;
}
}
Also -- I'm trying to get better at questions like these. Is this an ok approach for this question? I'd like to figure out how to make this work, but also if this is an all around bad approach please let me know.
break code into simple helper functions,
make a function to get value of nth element in the linked list(this function is very easy to write)
,and then traverse the list upto the half every time calling that function to get the value of listSize-i member of the list and edit the value of the the ith member of the list. and make changes to the 1st few elements manually to check weather your linkList implementation is working or not
/**
* Definition for singly-linked list.
**/
class ListNode {
public int val;
public ListNode next;
ListNode(int x) { val = x; next = null; }
}
public class Solution {
public ListNode subtract(ListNode a) {
ListNode current = a;
int length = 0;
//get length
while(current.next != null){
length++;
current = current.next;
}
length += 1;
int half = length/2;
//logic of this loop is
//go from 0 to half of the list
// j goes from the last element to half
//for example if size of list is 6 (indexing from 0)
//when i is 0 j is 5
//when i is 1 j is 4 and so on
//so you get what you wanted
for(int i=0,j=length-1; i<half; i++,j-- ){
current.val=nthElement(a,j).val-current.val;
current = current.next;
}
return a;
}
/* Helper function that given LinkedList head, and int n,
returns the nth node of LinkedList */
public ListNode nthElement(ListNode head, int n){ //e.g-if n is 5 it will return the 5th node
ListNode nth = head;
for(int i=0; i<n; i++){
nth = nth.next;
}
return nth;
}
}

How to determine the space and time complexity of these two algorithms?

I was practicing one algorithm exercise today from HackerRank: https://www.hackerrank.com/challenges/find-the-merge-point-of-two-joined-linked-lists
I decided to solve this problem with two solutions.
First algorithm, based on Floyd's algorithm:
/*
Insert Node at the end of a linked list
head pointer input could be NULL as well for empty list
Node is defined as
class Node {
int data;
Node next;
}
*/
int FindMergeNode(Node headA, Node headB) {
// Complete this function
// Do not write the main method.
int length1 = countLength(headA);
int length2 = countLength(headB);
int d = Math.abs(length1 - length2);
return (length1 > length2) ?
findIntersection(d, headA, headB) : findIntersection(d, headB, headA);
}
int countLength(Node head) {
Node current = head;
int counter = 0;
while (current != null) {
current = current.next;
counter++;
}
return counter;
}
int findIntersection(int d, Node headA, Node headB) {
Node currentA = headA;
Node currentB = headB;
for (int i = 0; i < d; i++) {
currentA = currentA.next;
}
while (currentA != null && currentB != null) {
if (currentA == currentB) return currentA.data;
currentA = currentA.next;
currentB = currentB.next;
}
return -1;
}
Second algorithm, using one outer and inner loop:
/*
Insert Node at the end of a linked list
head pointer input could be NULL as well for empty list
Node is defined as
class Node {
int data;
Node next;
}
*/
int FindMergeNode(Node headA, Node headB) {
Node currentA = headA;
while (currentA != null) {
Node currentB = headB;
while (currentB != null) {
if (currentA == currentB) {
return currentA.data;
}
currentB = currentB.next;
}
currentA = currentA.next;
}
return -1;
}
Honestly, I'm sure that the first algorithm is better than the second because of its performance. I would like to demonstrate this performance using SPACE and TIME COMPLEXITY, I have not dominated those topics.
According to the material, this solution should be Time Complexity: O(N). But I'm not quite sure that the first algorithm will be O(N).
The first algorithm scans headA and headB once to find the lengths, then skips the extra elements of the longer chain, then scans in parallel the two chains. The time complexity is proportional to the length of the chains, so it is O(N). It doesn't matter if you scan the lists 2, 3, or 5 times, as long as that number is constant, the time complexity is still O(N).
The second algorithm is worse, for each element in headA before the merge point, it scans the entire headB. In the worst case, when the lists don't intersect at the last node, it will scan all elements of headB for each element of headA. So the time complexity of this is O(N^2).
The space complexity of both algorithms is O(1), because you use constant storage in both (a bunch of local variables), that don't change, regardless the size of the input lists.
The first one is O(N) where N is in abstract the greatest of the two list length. Since you have two for loops and each can cost at max N, in the worst case the first algorithm will take 2 N cycle to end. So since O hide constant factor the algorithm is O(N)

Measure size/length of singly linked list in Java?

I need help making the int size(); method for a singly linked list in Java.
This is what I have so far, but it does not return the correct size of the list.
public int size()
{
int size = 0;
Node CurrNode = head;
while(CurrNode.next != null)
{
CurrNode = CurrNode.next;
size++;
}
return size;
}
Can someone help me implement this method in Java?
The biggest improvement you can make is to use Java Coding Convension and use camelCase local variables.
You can write it like this.
public int size() {
int size = 0;
for(Node n = head; n.next != null; n = n.next)
size++;
return size;
}
as you are re-writing a commonly used class in Java, I suggest you have a look at how it is done there if you want a better way of doing things.
From LinkedList
/**
* Returns the number of elements in this list.
*
* #return the number of elements in this list
*/
public int size() {
return size;
}
As you can see, when an element is added size is incremented and when an element is removed it id decremented saving you having to traverse the list to get the size.
The easiest way would be to have variable that tracks the size initialised at 0. Then each time you add a node it's just size++, or size-- when you remove a node. You size() method then just has to return this variable without traversing the list.
You need to pass the list to your method and check currNode!= null :
public static int size(Node currNode){
int count = 0;
while (currNode!= null){
count++;
currNode=currNode.getNext();
}
return count;
}
Well, the easiest way to calculate the length is by checking whether the currentNode!=null and keep the currentNode incrementing .
We can use while or a for loop to implement this.
Below is an example where for loop is used.
public int getLength(){
ListNode temp = head;
for(temp = head; temp!=null; temp=temp.getNextNode()){
length++;
}
return length;
}

Categories