So through LeetCode, I picked a question that asks to add 2 numbers from singly linked list. The following is the structure of LinkedList
public class ListNode {
int val;
ListNode next;
ListNode() {}
ListNode(int val) { this.val = val; }
ListNode(int val, ListNode next) { this.val = val; this.next = next; }
}
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode newNode = new ListNode(0);
ListNode head = newNode;
while(l1 != null)
{
newNode((((l1.val)+(l2.val))%10));
l1 = l1.next;
l2 = l2.next;
newNode = newNode.next;
newNode = new ListNode();
}
newNode.next = null;
return head;
}
}
It gives an error saying "cannot find symbol newNode....."
Assuming both lists are the same size or length, I first instantiated ListNode class to newNode, and then within while loop, I am simply calling the same class since it has a constructor that takes 1 parameter and I pass the value from both list module 10.
Its been a while since I am doing Java, is this not allowed in Java? I know the solution but I just don't know why the above won't work?
Related
This code has to remove the node of the value sent from LinkedList where head and the value is given
Can someone tell me what is wrong with the code?
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode removeElements(ListNode head, int val) {
if(head==null) return head;
if(head.val==val) {head=head.next;}
ListNode currentNode = head;
ListNode previousNode = head;
while(currentNode.val!=val) {
previousNode=currentNode;
currentNode = currentNode.next;
}
previousNode.next=currentNode.next;
removeElements(currentNode.next,val);
return head;
}
}
For the test case [7,7,7,7] expected answer is [] but the code is giving the output [7,7,7]
you just need to pass through the list and checking the current node and update the reference if needed
public ListNode removeElements(ListNode head, int val) {
if(head==null) return null;
if(head.val==val) return removeElements(head.next,val);
head.next = removeElements(head.next,val);
return head;
}
I'm working on the following problem Reverse Linked List from Leetcode:
Given the head of a singly linked list, reverse the list, and return the reversed list.
Class ListNode defined as follows:
public class ListNode {
int val;
ListNode next;
ListNode() {}
ListNode(int val) { this.val = val; }
ListNode(int val, ListNode next) { this.val = val; this.next = next; }
}
Here is the solution that I came up with.
class Solution {
public ListNode reverseList(ListNode head) {
if (head != null) {
ListNode pre = head;
ListNode cur = head.next;
ListNode temp;
while (cur != null) {
temp = cur.next;
cur.next = pre;
pre = pre.next; //here should be pre = cur; but I don't get it.
cur = temp;
}
head.next = null;
return pre;
} else {
return null;
}
}
}
To make it working inside the while-loop, I need change
pre = pre.next;
with
pre = cur;
But I still don't fully understand it.
After temp = cur.next;, variable pre should still be pointing to cur, right?
So what's wrong here? Can someone explain it in detail?
pre should still be pointing to cur, right? So what's wrong here?
pre = pre.next; // here should be pre = cur; but I don't get it.
When the while-loop terminates, cur points to null, so you need a reference to the previous node pre as a result.
Now let's take a closer look at the statement
pre = pre.next;
During the first step of iteration when pre points to head, this statement would be the same as pre = cur (effectively head.next). That fine.
But starting from the second iteration step, pre.next would point backwards, and that not what you need. You need to advance the reference pre to the tail (which would became a new head), not the opposite.
For that reason, you need pre = cur; instead.
You can get rid of the if-statement in your code and reimplement it like this:
public ListNode reverseList(ListNode head) {
ListNode pre = null;
ListNode cur = head;
while (cur != null) {
ListNode temp = cur.next;
cur.next = pre;
pre = cur;
cur = temp;
}
return pre;
}
main()
public static void main(String[] args) {
ListNode second = new ListNode(3);
ListNode first = new ListNode(2, second);
ListNode head = new ListNode(1, first);
ListNode newHead = reverseList(head);
while (newHead != null) {
System.out.println(newHead.val);
newHead = newHead.next;
}
}
Output:
3
2
1
A link to Online Demo
If you need to reverse singly linked list than I can give you a simpler solution
public class ListReverser {
public static Node<Integer> reverse(Node head) {
Node current = head;
while(current.getNext() != null) {
Node next = current.getNext();
current.setNext(next.getNext());
next.setNext(head);
head = next;
}
return head;
}
}
I wrote a small post on my LinkedIn page with this solution. Feel free to visit: Popular Java interview task: Reverse singly (one-directional) linked list
I have written the following code for reversing a linked list through recursion. However, it didn't work and when I debugged it I could see that the changes in each of the calls weren't being passed to the calls beneath it in the stack. For example, lets say we have linked list 1->2->null. The calls made will be reverse(null,1,null),reverse(1,2,null),then finally reverse(2,null,null). At the final call, as per my code new head should be changed to point at 2 which will then be constant throughout the rest of the stack calls since, I am sending in the reference of newHead to reverse. However, when this call is exited from the stack, then newHead goes back to being null in the previous call which is reverse(1,2,newHead:null). Not sure why this is happening. Can someone please explain to me why this is happening. I am really confused.
Thank you!!
public class ListNode {
int val;
ListNode next;
ListNode() {}
ListNode(int val) { this.val = val; }
ListNode(int val, ListNode next) { this.val = val; this.next = next; }
public static ListNode reverseList(ListNode head) {
if(head==null){
return null;
}
ListNode newHead = head;
reverse(null,head,newHead);
return newHead;
}
private static void reverse(ListNode prev, ListNode curr, ListNode newHead){
if(curr==null){
newHead = prev;
return;
}
reverse(curr,curr.next,newHead);
curr.next = prev;
}
public static void main(String[] args) {
ListNode head = new ListNode(1,new ListNode(2));
reverseList(head);
System.out.print(head.val);
}
}
When you pass a variable as argument to a function, like with reverse(head), you cannot expect that function to change the variable's value. head will still reference the same node after the call. The only thing you can expect from this, is that the function will mutate that node and adjust its next property (or any other property), but it cannot make head reference a different node.
When in reverse you assign like newHead = prev; that will only affect the value of newHead, which is a local variable. If you would do newHead.next = null, then yes, the property will change in that object, to which also the caller has access via their own variable. But that is mutation, while in your code you are not mutating, but assigning to a variable.
So make reverse return the new value, and let the caller capture that and assign it to their local variable, ...etc.
public static ListNode reverseList(ListNode head) {
if (head == null) {
return null;
}
ListNode newHead = head;
return reverse(null, head, newHead); // <-- return it
}
private static ListNode reverse(ListNode prev, ListNode curr, ListNode newHead) {
if (curr == null) {
return prev; // <-- return it
}
// Capture the returned node reference
newHead = reverse(curr, curr.next, newHead);
curr.next = prev;
return newHead; // <--- and bubble it up the recursive chain
}
public static void main(String[] args) {
ListNode head = new ListNode(1, new ListNode(2));
head = reverseList(head);
System.out.println(head.val); // 2
}
So I'm working this problem:Given the head of a sorted linked list, delete all duplicates such that each element appears only once. Return the linked list sorted as well.And test example is [1,1,2].
public static class ListNode {
int val;
ListNode next;
ListNode() {}
ListNode(int val) { this.val = val; }
ListNode(int val, ListNode next) { this.val = val; this.next = next; }
}
public static ListNode deleteDuplicates(ListNode head) {
ListNode l3=new ListNode(9);
ListNode l4 = l3;
if (head==null||head.next==null){
return head;
}
while (head.next!=null){
if(head.val== head.next.val){
head=head.next;
l3.next=head;
}else {
l3.next=head;
head=head.next;
//when I debug until this line,it will creat infinite list like[1,1,1,1,.......,1,1,1]
}
l3=l3.next;
}
return l4.next;
}
So as you can see in the code,why will it creat infinite list when test example is[1,1,2]?
I write a code by java in leetCode, this is the link:
https://leetcode.com/problems/reverse-linked-list/description/
it shows "Memory Limit Exceeded", can anyone explain why?(you can just paste my code to the above link to see the error)
My code is as follows:
public static class ListNode {
int val;
ListNode next;
ListNode(int x) { val = x; }
}
public ListNode reverseList(ListNode head) {
if(head ==null)
return head;
if(head.next ==null){
return head;
}
Stack<ListNode> mStack =new Stack<>();
while(head!=null){
mStack.push(head);
head = head.next;
}
ListNode mNode = new ListNode(0);
ListNode result =mNode;
while(!mStack.empty()){
ListNode temp = mStack.pop();;
mNode.next = temp;
mNode = mNode.next;
}
return result.next;
}
The problem is that, suppose the input is 1->2->3. Then what you will return is
3->2->1->2->1->2.....
This circular linked list will cause Memory Limit Exceeded when calling toString method.
To solve this, just set the next of original head to null.
This is because they expect you to do it in constant space complexity. A simple recursive solution would be :
class Solution {
public ListNode reverseList(ListNode head) {
if (head==null){
return head;
}
return reverseList(head,null);
}
public ListNode reverseList(ListNode current,ListNode prev){
if (current.next==null){
// we have reached the last node. This will be the new head
current.next = prev;
return current;
}
ListNode head = reverseList(current.next,current);
current.next=prev;
return head;
}
}