I am trying to develop a way in which I can solve Linked list problems without having to care about the head node in any special way i.e. In linked list problems we usually deal with the head pointer separately before we start with the next nodes.
I found a way: Use a dummy node so that the actual linked list begins from dummy.next.
I am trying to solve a problem using that way:
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode dummy = ListNode(0);
ListNode * temp = dummy.next;
int carry =0;
while(l1!=NULL && l2!=NULL)
{
int x = (l1->val + l2->val + carry)%10;
temp = new ListNode(x);
carry = (l1->val + l2->val + carry)/10;
temp = temp->next;
l1 = l1->next;
l2 = l2->next;
}
ListNode * p = (l1!=NULL)?l1:l2;
while(p!=NULL)
{
int x = (p->val+carry)%10;
temp = new ListNode(x);
carry = (p->val+carry)/10;
temp = temp->next;
p = p->next;
}
if(carry==1) temp = new ListNode(1);
return dummy.next;
}
int main()
{
ListNode * l1 = new ListNode(0), *l2 = new ListNode(0);
ListNode * l3 = addTwoNumbers(l1,l2);
}
In this problem I tried not to initialize a head node separately. Obviously, the code does not do what I want it to, but I tried this way and now, I can't figure out how to proceed in this approach.
That is, Use the dummy node so that there is no need to separately handle the head node of the newly created linked list.
Any way to use this approach to solve the problem ?
Follow this approach
ListNode * addTwoLists(ListNode * first, ListNode * second) {
ListNode * res = NULL, * temp, * prev = NULL;
int carry = 0, sum;
while (first != NULL || second != NULL) {
sum = carry + (first ? first->val : 0) + (second ? second->val : 0);
carry = (sum >= 10) ? 1 : 0;
sum %= 10;
temp = new ListNode(sum);
if (res == NULL)
res = temp;
else
prev->next = temp;
prev = temp;
if (first) first = first->next;
if (second) second = second->next;
}
if (carry > 0)
temp->next = new ListNode(carry);
return res;
}
These parts are your problem:
temp = new ListNode(x);
carry = (l1->val + l2->val + carry)/10;
temp = temp->next;
You create a new ListNode, then with temp = temp->next just forget it. temp->next is NULL at that time and you lose any ability to access your previously created ListNode, let alone modify it's next pointer.
Start over. This is broken by design.
With or without a dummy node, a key part of building a new list is staying one node behind where you logically are. I prefer to do so without a dummy node, so the pointer used for current position is ListNode** temp and you allocate new nodes with (*temp)=new ListNode(x) and advance to the next (predecessor) position with temp=&(*temp)->next. If you prefer to use a dummy node, you use ListNode* temp=&dummy; and allocate new nodes with temp->next=new ListNode(x) and advance with temp=temp->next only after your logical position is one beyond that.
Edit based on your comment. If you want to avoid the syntax (not reality) of the double pointer:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode dummy = ListNode(0);
ListNode * temp = &dummy;
int carry =0;
while(l1!=NULL || l2!=NULL)
{
if (l1!=NULL)
{
carry += l1->val;
l1 = l1->next;
}
if (l2!=NULL)
{
carry += l2->val;
l2 = l2->next;
}
temp = temp->next = new ListNode(carry%10);
carry /= 10;
}
if(carry==1) temp->next = new ListNode(1);
return dummy.next;
}
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 months ago.
Improve this question
I had a runtime error:
member access within null pointer of type 'ListNode'.
at the line (current_3->val = digit;)
UndefinedBehaviorSanitizer: undefined-behavior prog_joined.cpp:33:24
I don't know what this error means. Could you explain the problem and how I can solve it, please?
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
int carry = 0;
int sum, digit=0;
ListNode l3;
ListNode *current_1 = l1->next;
ListNode *current_2 = l2->next;
ListNode *current_3 = l3.next;
while (current_1 != NULL && current_2 != NULL) {
sum = current_1->val + current_2->val + carry;
digit = sum % 10;
carry = sum / 10;
current_3->val = digit;
current_1 = current_1->next;
current_2 = current_2->next;
current_3 = current_3->next;
}
return &l3;
}
};
Here's how you might do this. I haven't seen the original problem, so this might not be correct, however it does allocate the nodes for the list correctly.
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
int carry = 0;
ListNode* head = NULL;
ListNode* tail = NULL;
while (l1 != NULL && l2 != NULL) {
int sum = l1->val + l2->val + carry;
int digit = sum % 10;
carry = sum / 10;
ListNode* tmp = new ListNode(digit); // allocate a new node
if (head == NULL) // if the list is empty
head = tmp; // then head points to the new node
else
tail->next = tmp; // otherwise add to the end of the list
tail = tmp; // tail points to the new end of the list
l1 = l1->next;
l2 = l2->next;
}
return head;
}
Notice how each digit added to the list has a node allocated with new ListNode(digit). The head variable points to the beginning of the list, and the tail variable points to the last node in the list, allowing you to efficiently add new nodes to the end of the list. This is a classic way of building a linked list.
I'm doing LeetCode problem 2 Add Two Numbers. The description is:
You are given two non-empty linked lists representing two non-negative
integers. The digits are stored in reverse order, and each of their
nodes contains a single digit. Add the two numbers and return the sum
as a linked list.
You may assume the two numbers do not contain any leading zero, except
the number 0 itself.
Example:
Input: l1 = [2,4,3], l2 = [5,6,4]
Output: [7,0,8]
Explanation: 342 + 465 = 807.
Note the two linked list can be in different length
My idea is to sum each digit from l1 and l2 call it v3. Mod it by 10 (v3%10) to find out the digit I need to insert to the new linked list. And divide it by 10 to figure out if I need to encounter the carry. However, my solution is not returning anything, and I can not figure out why...
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode *dummy = NULL;
int v3 = 0;
int carry = 0;
while (l1 && l2 && v3 > 0){
int v1 = l1->val;
int v2 = l2->val;
// when l1 reaches the end. Set v1 to 0
if(l1->next == NULL){
v1 = 0;
}
if(l2->next == NULL){
v2 = 0;
}
v3 = (v1 + v2 + carry);
carry = v3 / 10;
int insert_value = v3 % 10;
ListNode *newNode = new ListNode(insert_value);
if(dummy == NULL){
dummy = newNode;
} else {
ListNode *head = dummy;
while (dummy->next){
dummy = dummy->next;
dummy->next = newNode;
dummy = head;
}
}
if(l1->next != NULL){
l1 = l1->next;
}
if(l2->next != NULL){
l2 = l2->next;
}
}
return dummy;
}
};
Your loop condition is not quite correct, it should be something like:
ListNode *r = nullptr;
ListNode **curr = &r;
bool carry = false;
while( l1 || l2 || carry ) {
int v = carry;
if( l1 ) {
v += l1->val;
l1 = l1->next;
}
if( l2 ) {
v += l2->val;
l2 = ;2->next;
}
carry = v >= 10;
(*curr)->next = new ListNode( v % 10 );
curr = &(*curr)->next;
}
I did not test this code but idea should be clear
#Slave
Okay got it. Had to try out the pointer. But it did work. Thank you!
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode *node = NULL;
ListNode **cur = &node;
bool carry = false;
while(l1 || l2 || carry){
int val = carry;
if(l1){
val += l1->val;
l1 = l1->next;
}
if(l2){
val += l2->val;
l2 = l2->next;
}
carry = val >= 10;
*cur = new ListNode(val%10);
cur = &((*cur)->next);
}
return node;
}
};
The following code is supposed to take an integer (which is numerator) and convert it into a linked list, starting from the very end. As an example, for the integer 603, I want to create 3->0->6. But for some reason, my output only gives me 0->6, and completely ignores the 3? I've looked over my code and I just can't seem to see where my logic is going wrong.
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
}
int numerator = sum1 + sum2;
ListNode * ptr;
while (numerator != 0) {
int val = numerator % 10;
numerator = numerator / 10;
ListNode * node = new ListNode(val);
// If list is empty, add node.
if (!ptr) {
ptr = node;
// If list is not empty, traverse to end of list and then append.
} else {
while (ptr->next) {
ptr = ptr->next;
}
ptr->next = node;
}
}
Your code loses the head of the list because it is stored in ptr which is changed on each insertion.
You can append a node to a singly-linked list in a more efficient manner:
ListNode* head = 0;
ListNode** tail = &head;
// ...
// Append the new node to the tail of the list.
ListNode* node = new ListNode(val);
*tail = node;
tail = &node->next;
i need to make a function to sum 2 piecewise linear functions (both decreasing or increasing) and insert them into a third list in an ascending order based on the x-axis coordinates of each point. So i have created multiple functions, all seem to check out except this one yet i do not know what's the problem. It's not inputting anything at all.
struct coords has double x,y;
dList has : coords pt;
node has : node *head, *tail;
node *prev, *next;
dList insert(dList L, coords point) {
node *temp;
temp = new node;
if (temp == NULL) {
cout << "error";
exit(1);
}
temp->next = NULL;
temp->prev = NULL;
temp->pt = point;
if (L.head == NULL || L.tail == NULL) {
L.head = temp;
L.tail = temp;
return L;
}
if (L.head->pt.x > temp->pt.x) {
temp->next = L.head;
L.head->prev = temp;
L.head = temp;
return L;
}
if (L.tail->pt.x < temp->pt.x) {
temp->prev = L.tail;
L.tail->next = temp;
L.tail = temp;
return L;
}
node *cur;
cur = L.head->next;
while (cur->pt.x < temp->pt.x)
cur = cur->next;
temp->next = cur->next;
temp->prev = cur;
cur->next->prev = temp;
cur->next = temp;
return L;
}
The case in which the node to be inserted is in the middle is the problem. You should be looking one node ahead instead of looking at the current one. Try working it out on paper and you will see how that makes a difference:
node * cur;
// also start at head here
cur=L.head;
while(cur->next->pt.x<temp->pt.x)
cur=cur->next;
temp->next=cur->next;
temp->prev=cur;
cur->next->prev=temp;
cur->next=temp;
You should also consider passing a dList L as a pointer to the function and also returning it as a pointer:
// this way you won't be making a copy of it, you may run into trouble if you don't have your copy constructor implemented
dList* insert(dList* L,coords point)
I hope that this helps you.
I'm trying to incorporate push/pop into a linked list and I can't seem to get it to work. When I run my test function, I set my linked list to zero and I try to push on values but the list keeps getting returned with no values in it. Could anyone possibly tell me what I'm doing wrong?
if (top == NULL){
current = top;
current->next = NULL; //NULL->next : will cause segfault
}
if top is NULL, you set current = top [which is NULL], and then you access current->next, which will cause a segfault, you are trying to access NULL..
EDIT: follow up to comments:
your if statement seems redundant, you should probably only need to set: current->next = head; and head = current; [in addition to the current allocation]
Instead of
if (top == NULL){
current = top;
current->next = NULL;
}
you want
if (top == NULL){
top = current;
current->next = NULL;
}
And of course, after this, you have to make sure that you actually set head to top again.
Now that you've made this change, it should be clear that both cases do the same thing -- so no case distinction is actually necessary. So the function can be simplified to
void push(Data * newPushData){
LinkNode * current = new LinkNode(newPushData);
current->next = head;
head = current;
}
The top variable is local variable for push(...) function. You can use head instead, and I'd rather modify the if statement.
I think that function should look like this:
void push(Data * newPushData){
LinkNode * current = new LinkNode(newPushData);
if (head != NULL){
current->next = head;
head = current;
}
else{
head = current;
current->next = NULL; // if you haven't done it in LinkNode constructor
}
}
can you please specify the attributes of the linked list class ? [ is there slightly chance you are doing something wrong]
Instead of you , I'd do :
void push(Data * newPushData){
if (head == NULL)
head->data = newPushData
tail = head ;
else // regular situation
{
Node * node = new Node() ;
tail->next = node;
node->data = newPushData;
node->next = NULL ;
tail = node ;
}
}
In a linked list you have got to maintain the head pointer point on the head of the list , maintain that the tail pointer is point on the tail of the list ,
You must take care of the 2 cases of enlarging the list.
the best way for learning is to illustrate an insertion on a blank linked list.
Take care
S
void push(Data * newPushData)
{
if( head != NULL )
{
LinkNode current = new LinkNode(newPushData);
current->next = head;
head = current;
}
else
{
head = new LinkNode(newPushData);
}
}
Try this code...
void push(data * newpushdata){
if(head !=null){
linkednode current = new linkednode(newpushdata);
current->next = head;
head = current;
}
else {
head = new linkednode(newpushdata);
}
}
that is my working solution for a Stack containing int elements, but maybe it's better to create a void pushStack using Stack **S instead of Stack *S.
in pop(Stack **S) i created a sentinel, so if the stack is empty -1 is returned.:
typedef struct StackT {
int val;
struct StackT *next;
} Stack;
int isStackEmpty (Stack *S) {
if (S == NULL)
return 1;
else
return 0;
}
int *pop(Stack **S) {
Stack *tmp = *S;
int i = -1;
if (isStackEmpty(tmp) == 0) {
i = tmp->val;
*S = tmp->next;
}
return i;
}
Stack *pushStack (Stack *S, int x) {
Stack *node = (Stack *) malloc (sizeof (Stack));
node->val = x;
node->next = S;
return node;
}
you can call pop and stack easly:
Stack *S = NULL;
int x = somevalue;
int y;
S = pushStack(S, x);
y = pop(&S);