I just wrote a program that add two polynomial linked-list. my output only prints first term of the polynomials.
I cannot figure out what bug is. I want to get some help here. could someone tell what's wrong with my code.
public void addNode(int cof, int exp) {
PNode node = new PNode(cof, exp);
if (first == null) {
first = last = node;
return;
}
last.next = node;
last = node;
}
public PolynomialLinkedList add(PolynomialLinkedList s) {
PolynomialLinkedList sum = new PolynomialLinkedList();
//implement this method
PNode list1 = first;
PNode list2 = s.first;
while (list1 != null && list2 != null) {
if (list1.exp == list2.exp) {
sum.addNode(list1.coe + list2.coe, list1.exp);
list1 = list1.next;
list2 = list2.next;
} else if (list1.exp > list2.exp) {
sum.addNode(list1.coe, list1.exp);
list1 = list1.next;
} else if (list2.exp > list1.exp) {
sum.addNode(list2.coe, list2.exp);
list2 = list2.next;
}
}
return sum;
}
If one of the lists finishes first, the rest of the items in other list are ignored and are not getting added to the sum.
Add additional loops
while(list1 != null) {
sum.addNode(list1.coe,list1.exp);
list1=list1.next;
}
and
while(list2 != null) {
sum.addNode(list2.coe,list2.exp);
list2=list2.next;
}
Related
I have two lists ItemsList , ilist . If the nodes of ilist contain the same values as the nodes of ItemsList i have to delete them from ItemsList however i get that my list is empty each time i use the remove function from the code below :
public void remove(ItemsList ilist) {
if (empty()) {
System.out.println("The list is empty.");
} else {
this.bubblesort();
ilist.bubblesort();
ItemNode a = this.first;
ItemNode b = ilist.first;
for(a=first;a!=null;a=a.next) {
for(b=first;b!=null;b=b.next) {
if(a.item==b.item) {
this.deleteNode(a.item);
}
}
}
}
}
private void deleteNode(int data) {
ItemNode prev = null;
for(ItemNode trace = first; trace != null; trace = trace.next) {
if(trace.item == data) {
if (prev == null) {
first = trace.next;
} else {
prev.next = trace.next;
}
}
else {
prev = trace;
}
}
}
Lets say i have ItemsList : [0,1,2,3,4] and ilist : [0,1] which means 0 ,1 will be deleted from ItemsList but when i display the ItemsList it says that it's empty . I cannot use arrays , arraylists or other java libraries for the specific problem . Thank you for your time .
What I would do:
public void remove(ItemsList iList) {
if (iList.isEmpty()) {
System.out.println("The list is empty.");
} else {
ItemNode prev = null;
ItemNode a = this.first;
while (a != null) {
for (ItemNode b = iList.first; b != null; b = b.next) {
if (a.item == b.item) prev.next = a.next;
}
a = a.next;
}
}
}
So Natural mergeSort is a variation on mergeSort that instead of splitting the list into halves, you iterate through the list, make 2 new temp lists that are "naturally sorted" and then sort those 2 lists.
e.g. List = 1, 3, 2, 4, 5, null
The first temp list == 1, 3 because 1 < 3, but 3 is not < 2
The second temp list == 2, 4, 5
Next step is to compare first temp list with second temp list
if( firstTemp > secondTemp)
swap;
My problem comes from creating these 2 separate lists.
When I create the 2 new lists, it's erasing my original list. Also I can't seem to get my counter right for creating the size of the lists. A new list doesn't seem to act like a new list because the counter keeps incrementing from the original list to the new lists.
Like the e.g. above,
ogList.size = 5
then
firstTemp.size = 7
secondTemp.size = 10
When it should be
firstTemp.size = 2
and
secondTemp.size = 3
package mergesortlinkedlist;
public class MergeSortLinkedList {
static LinkedList list = new LinkedList();
public static void main(String[] args) {
//
// start linked list
//
LinkedList.push(list, 1);
LinkedList.push(list, 3);
LinkedList.push(list, 2);
LinkedList.push(list, 4);
LinkedList.push(list, 5);
list.printList(list);
System.out.println("list size = " + list.head.getCounter());
naturalMerge(list);
}
public static void naturalMerge(LinkedList front) {
LinkedList set1 = new LinkedList();
LinkedList set2 = new LinkedList();
LinkedList temp = front;
//get first temp list
while (temp != null) {
if (temp.head.data < temp.head.next.data) {
LinkedList.push(set1, temp.head.data);
temp.head = temp.head.next;
} else {
LinkedList.push(set1, temp.head.data);
temp.head = temp.head.next;
break;
}
}
//get second temp list
while (temp != null) {
if (temp.head.data < temp.head.next.data) {
LinkedList.push(set2, temp.head.data);
temp.head = temp.head.next;
} else {
LinkedList.push(set2, temp.head.data);
temp.head = temp.head.next;
break;
}
}
mergeSwap(set1, set2);
}
public static void mergeSwap(LinkedList set1, LinkedList ){
//template code to swap the naturally sorted temp lists
}
}
}
public class LinkedList {
public Node head;
public static class Node {
public Node next = null;
public Integer data;
public static int counter = 0;
Node() {
}
Node(int d) {
this.data = d;
}
public void setCounter(int n) {
counter += n;
}
public int getCounter() {
return counter;
}
}
public static void push(LinkedList list, int data) {
// Create a new node with given data
Node new_node = new Node(data);
new_node.next = null;
// If the Linked List is empty,
// then make the new node as head
if (list.head == null) {
list.head = new_node;
new_node.setCounter(1);
} else {
// Else traverse till the last node
// and insert the new_node there
Node last = list.head;
while (last.next != null) {
last = last.next;
}
// Insert the new_node at last node
last.next = new_node;
new_node.setCounter(1);
}
// Return the list by head
//return list;
}
I'm just wondering if this version of my code is possible for creating separate lists for natural mergeSort. Am I able to use this code to make new lists without destroying the original list?
Ultimately, I want my list = 1,2,3,4,5,null
Ok well I changed some things, it's not able to do recurssive calls, which makes me think the logic isn't working right, but I'm still able to sort the list.
Instead of calling
naturalMerge(list);
after swapping nodes, I do it from main. The only reason is because for some reason I get a null pointer exception.
I'd like to come back to this and make it work better, but for now it'll probably do for getting my assignment turned in.
package mergesortlinkedlist;
public class MergeSortLinkedList {
// static Node first = new Node();
static LinkedList list = new LinkedList();
public static void main(String[] args) {
// start linked list
list.add(list, 1);
list.add(list, 5);
list.add(list, 3);
list.add(list, 4);
list.add(list, 2);
list.add(list, 100);
list.add(list, 76);
list.add(list, -6);
list.printList(list);
naturalMerge(list);
list.printList(list);
naturalMerge(list);
list.printList(list);
naturalMerge(list);
list.printList(list);
}
public static void naturalMerge(LinkedList front) {
LinkedList set1 = new LinkedList();
LinkedList set2 = new LinkedList();
LinkedList temp = front;
int size1 = 0;
int sortCounter = 0; //if sortCounter != 0, then there is more to sort
//get first temp list
while (temp.head.data != null) {
if (temp.head.data < temp.head.next.data) {
set1.add(set1, temp.head.data);
size1++;
temp.head = temp.head.next;
} else {
set1.add(set1, temp.head.data);
size1++;
temp.head = temp.head.next;
break;
}
}
//get second temp list
while (temp.head != null) {
if (temp.head.next == null) {
set2.add(set2, temp.head.data);
temp.head = temp.head.next;
break;
}
if (temp.head.data < temp.head.next.data) {
set2.add(set2, temp.head.data);
temp.head = temp.head.next;
} else {
set2.add(set2, temp.head.data);
temp.head = temp.head.next;
break;
}
}
mergeSwap(set1, set2, size1);
}
public static void mergeSwap(LinkedList set1, LinkedList set2, int size1) {
System.out.println();
LinkedList temp = set1;
LinkedList temp2 = set2;
while (temp.head != null && temp2.head != null) {
if (temp.head.data < temp2.head.data) {
list.add(list, temp.head.data);
temp.head = temp.head.getNext(); //increment temp
} else {
list.add(list, temp2.head.data);
temp2.head = temp2.head.getNext(); //increment temp2
}
//if one list is empty, break loop and add remaining nodes
if (temp.head == null || temp2.head == null) {
break;
}
}
//check which list is empty, and add the remaining nodes to original list
if (temp.head == null) {
while (temp2.head != null) {
list.add(list, temp2.head.data);
temp2.head = temp2.head.getNext();
}
} else {
while (temp.head != null) {
list.add(list, temp.head.data);
temp.head = temp.head.getNext();
}
}
//naturalMerge(list); //this call breaks the code, but why? How is it any different from the method call in main?
}
}
I was doing this exercice:
Write code to partition a linked list around a value x, such that all nodes less than x come before all nodes greater than or equal to x. Example input: 3 -> 5 -> 8 -> 5 -> 10 -> 2 -> 1 output: 3 -> 1 -> 2 -> 10 -> 5 -> 5 -> 8
I found it hard to find a solution for Singly linked list (that created by my own, not using library), I would like to know if there is uncessary code blocks in my code and is there a way to avoid putting in two lists and then merge? because it seems to have very slow performance like that.
public CustomLinkedList partition(CustomLinkedList list, int x) {
CustomLinkedList beforeL = new CustomLinkedList();
CustomLinkedList afterL = new CustomLinkedList();
LinkedListNode current = list.getHead();
while (current != null) {
if (current.getData() < x) {
addToLinkedList(beforeL, current.getData());
} else {
addToLinkedList(afterL, current.getData());
}
// increment current
current = current.getNext();
}
if (beforeL.getHead() == null)
return afterL;
mergeLinkedLists(beforeL, afterL);
return beforeL;
}
public void addToLinkedList(CustomLinkedList list, int value) {
LinkedListNode newEnd = new LinkedListNode(value);
LinkedListNode cur = list.getHead();
if (cur == null)
list.setHead(newEnd);
else {
while (cur.getNext() != null) {
cur = cur.getNext();
}
cur.setNext(newEnd);
cur = newEnd;
}
}
public void mergeLinkedLists(CustomLinkedList list1, CustomLinkedList list2) {
LinkedListNode start = list1.getHead();
LinkedListNode prev = null;
while (start != null) {
prev = start;
start = start.getNext();
}
prev.setNext(list2.getHead());
}
CustumLinkedList contains two attributes: -LinkedListNode which is the head and an int which is the size.
LinkedListNode contains two attributes: One of type LinkedListNode pointing to next node and one of type int: data value
Thank you.
The problem of your code is not merging two lists as you mentioned. It's wrong to use the word merge here because you're only linking up the tail of the left list with head of right list which is a constant time operation.
The real problem is - on inserting a new element on the left or right list, you are iterating from head to tail every time which yields in-total O(n^2) operation and is definitely slow.
Here I've wrote a simpler version and avoid iterating every time from head to insert a new item by keeping track of the current tail.
The code is very simple and is definitely faster than yours(O(n)). Let me know if you need explanation on any part.
// I don't know how your CustomLinkedList is implemented. Here I wrote a simple LinkedList node
public class ListNode {
private int val;
private ListNode next;
public ListNode(int x) {
val = x;
}
public int getValue() {
return this.val;
}
public ListNode getNext() {
return this.next;
}
public void setNext(ListNode next) {
this.next = next;
}
}
public ListNode partition(ListNode head, int x) {
if(head == null) return null;
ListNode left = null;
ListNode right = null;
ListNode iterL = left;
ListNode iterR = right;
while(iter != null) {
if(iter.getValue() < x) {
iterL = addNode(iterL, iter.getValue());
}
else {
iterR = addNode(iterR, iter.getValue());
}
iter = iter.getNext();
}
// link up the left and right list
iterL.setNext(iterR);
return left;
}
public ListNode addNode(ListNode curr, int value) {
ListNode* newNode = new ListNode(value);
if(curr == null) {
curr = newNode;
} else {
curr.setNext(newNode);
curr = curr.getNext();
}
return curr;
}
Hope it helps!
If you have any list of data, access orderByX Method.
Hope it would help you.
public class OrderByX {
Nodes root = null;
OrderByX() {
root = null;
}
void create(int[] array, int k) {
for (int i = 0; i < array.length; ++i) {
root = insert(root, array[i]);
}
}
Nodes insert(Nodes root, int data) {
if (root == null) {
root = new Nodes(data);
} else {
Nodes tempNew = new Nodes(data);
tempNew.setNext(root);
root = tempNew;
}
return root;
}
void display() {
Nodes tempNode = root;
while (tempNode != null) {
System.out.print(tempNode.getData() + ", ");
tempNode = tempNode.getNext();
}
}
void displayOrder(Nodes root) {
if (root == null) {
return;
} else {
displayOrder(root.getNext());
System.out.print(root.getData() + ", ");
}
}
Nodes orderByX(Nodes root, int x) {
Nodes resultNode = null;
Nodes lessNode = null;
Nodes greatNode = null;
Nodes midNode = null;
while (root != null) {
if (root.getData() < x) {
if (lessNode == null) {
lessNode = root;
root = root.getNext();
lessNode.setNext(null);
} else {
Nodes temp = root.getNext();
root.setNext(lessNode);
lessNode = root;
root = temp;
}
} else if (root.getData() > x) {
if (greatNode == null) {
greatNode = root;
root = root.getNext();
greatNode.setNext(null);
} else {
Nodes temp = root.getNext();
root.setNext(greatNode);
greatNode = root;
root = temp;
}
} else {
if (midNode == null) {
midNode = root;
root = root.getNext();
midNode.setNext(null);
} else {
Nodes temp = root.getNext();
root.setNext(midNode);
midNode = root;
root = temp;
}
}
}
resultNode = lessNode;
while (lessNode.getNext() != null) {
lessNode = lessNode.getNext();
}
lessNode.setNext(midNode);
while (midNode.getNext() != null) {
midNode = midNode.getNext();
}
midNode.setNext(greatNode);
return resultNode;
}
public static void main(String... args) {
int[] array = { 7, 1, 6, 2, 8 };
OrderByX obj = new OrderByX();
obj.create(array, 0);
obj.display();
System.out.println();
obj.displayOrder(obj.root);
System.out.println();
obj.root = obj.orderByX(obj.root, 2);
obj.display();
}
}
class Nodes {
private int data;
private Nodes next;
Nodes(int data) {
this.data = data;
this.next = null;
}
public Nodes getNext() {
return next;
}
public void setNext(Nodes next) {
this.next = next;
}
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
}
I think that maintaining two lists is not an issue. It is possible to use a single list, but at the cost of loosing some of the simplicity.
The principal problem seems to be the addToLinkedList(CustomLinkedList list, int value) method.
It iterates throughout the entire list in order to add a new element.
One alternative is to always add elements at the front of the list. This would also produce a valid solution, and would run faster.
What am I missing to allow me to remove a node(boxcar) to the end of my linked list?
public void removeBoxcarFromEnd() {
Boxcar prevcar = head;
Boxcar nextcar = head;
if (head.next == null) {
int result = head.data;
head = null;
return result;
}
else {
while (nextcar.next() > 2)
prevcar = nextcar;
nextcar = nextcar.next();
}
prevcar.setNext(null);
size--;
}
There are a few problems with this approach:
you're method is a void whereas you want to return the data of the last item?
your while loop doesn't use brackets ({}) nor indentation, therefore only prevcar = nextcar will be executed an infinite amount of times.
you use >2;
there is a cornercase where the linked list can be empty as well.
A probably better way to handle this:
public String removeBoxcarFromEnd() {
String result;
if(head == null) { //empty list
return null; //or do something else? throw an exception?
} else if (head.next() == null) { //one element, remove it
int result = head.data();
head = null;
}
else { //more elements
Boxcar prevcar = head, nextcar = head.next(), ffcar = nextcar.next();
while (ffcar != null) { //double next iteration
prevcar = nextcar;
nextcar = ffcar;
ffcar = ffcar.next();
}
int result = nextcar.data(); //get result
prevcar.setNext(null); //remove it from the linked list
}
size--;
return result;
}
Assuming you don't need to fetch data, only remove the last Boxcar:
public void removeBoxcarFromEnd() {
Boxcar prevcar = head;
Boxcar nextcar = head;
if (head == null || head.next() == null) {
return;
}
while (nextcar.next() != null) {
prevcar = nextcar;
nextcar = nextcar.next();
}
prevcar.setNext(null);
}
First we check for a null or one-element list; in those cases, there's nothing to do.
Next we walk the list until we get to the end (i.e. nextCar.next() returns null). At each step, we save the Boxcar that we're passsing.
When we exit the loop, prevcar points to the second-to-last car, and we can safely set its next variable to null.
I am trying to solve this problem https://oj.leetcode.com/problems/binary-tree-preorder-traversal/ , i.e. preorder traversal with recursive slution.
EDIT: The whole code:
import java.util.ArrayList;
import java.util.List;
public class Solution {
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
static List<Integer> res = new ArrayList<Integer>();
public List<Integer> preorderTraversal(TreeNode root) {
if(root == null){
return new ArrayList<Integer>();
}
res.add(root.val);
if(root.left != null){
res.add(preorderTraversal(root.left));
}
if(root.right != null){
res.add(preorderTraversal(root.right));
}
return res;
}
}
I have wrong answer because of the following:
Input: {1,2}
Output: [1,1,2]
Expected: [1,2]
Can someone tell me how to fix this?
EDIT: I dont have main() method or unit tests. If you open the link that I posted you will see that this is online judging system.
The problem is that within each recursive loop, you are adding the entire array again into your final result.
For example, given the following tree:
1
/
2
Your first iteration adds 1 into 'res' variable. The problem is when it gets to this line:
res.add(preorderTraversal(root.left));
Then it recursively calls itself for the left side. That preorderTraversal will return the res array, which will be [1,2]. Hence, when [1,2] gets added to res (which was [1], remember?), then you get [1,1,2].
Here's code that should work:
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<Integer>();
if(root == null){
return result;
}
result.add(root.val);
if(root.left != null){
result.addAll(preorderTraversal(root.left));
}
if(root.right != null){
result.addAll(preorderTraversal(root.right));
}
return result;
}
For the left and right nodes, just call preorderTraversal recursively, and it will add the values to res. Calling add/addAll on res with the results of these recursive calls is wrong.
public class Solution {
List<Integer> res = new ArrayList<Integer>();
public List<Integer> preorderTraversal(TreeNode root) {
if(root == null){
return new ArrayList<Integer>();
}
res.add(root.val);
if(root.left != null){
preorderTraversal(root.left);
}
if(root.right != null){
preorderTraversal(root.right);
}
return res;
}
}
There's a little problem with this solution -- res retains the values from previous calls, so calling preorderTraversal more than once on the same instance may return incorrect results. Here's a solution that does not have this drawback:
public class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<Integer>();
preorderTraversal(root, res);
return res;
}
private void preorderTraversal(TreeNode node, List<Integer> res) {
if (node != null) {
res.add(node.val);
preorderTraversal(node.left, res);
preorderTraversal(node.right, res);
}
}
}
try this method code:
public List<Integer> preorderTraversal(TreeNode root) {
if(root == null){
return new ArrayList<Integer>();
}
res.add(root.val);
if(root.left != null){
res = preorderTraversal(root.left);
}
if(root.right != null){
res = preorderTraversal(root.right);
}
return res;
}
btw, you were doing res.add in the recursion. You should rather do res= in it.
A working solution :
import java.util.ArrayList;
import java.util.List;
class TreeNode
{
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
class Solution {
public List<Integer> preorderTraversal(TreeNode root)
{
ArrayList<Integer> res = new ArrayList<Integer>();
if(root == null)
return res;
else res.add(root.val);
if(root.left != null)
{
res.add(root.left.val);
preorderTraversal(root.left);
}
if(root.right != null)
{
res.add(root.right.val);
preorderTraversal(root.right);
}
return res;
}
}
public class TreeTest
{
public static void main(String[] args)
{
Solution c = new Solution();
TreeNode t1 = new TreeNode(1);
TreeNode t2 = new TreeNode(2);
TreeNode t3 = new TreeNode(3);
//Link the nodes of the tree
t1.left = t2;
t1.right = t3;
List<Integer> list = c.preorderTraversal(t1);
System.out.println(list);
}
}
Since you have not posted the whole code how the input is done and output is produced it is difficult to tell. For preorder traversal it should be something like this.
void traverse(TreeNode node){
if(node != null){
res.add(node.val);
traverse(root.left);
traverse(root.right);
}
}
public ArrayList<E> getPreOrderTraversal() {
return getPreOrderTraversal(root);
}
private ArrayList<E> getPreOrderTraversal(Node tree) {
ArrayList<E> list = new ArrayList<E>();
if (tree != null) {
list.add((E) tree.value);
list.addAll(getPreOrderTraversal(tree.left));
list.addAll(getPreOrderTraversal(tree.right));
}
return list;
}
A working and LeetCode accepted solution:
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> list = new ArrayList<>();
return preOrderTraversalInternal(root, list);
}
private List<Integer> preOrderTraversalInternal(TreeNode root, List<Integer> list){
if(root == null) return list;
list.add(root.val);
if(root.left != null){
preOrderTraversalInternal(root.left, list);
}
if(root.right != null){
preOrderTraversalInternal(root.right, list);
}
return list;
}
}
The problem is that within each recursive loop, you are adding the entire array again into your final result.
You need to add left or right nodes only one time while traversing but in your code whole arr is getting added to the new res array.
This result will contain repetitive nodes.
For these issues, please use Print statements after every recursive call to debug the problem.
Solution -
Use addAll method: res.addAll(node.left);