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;
}
};
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.
This code add Two sum integer using linkedList.
I have added to the struct ListNode a new constructor in order to give him as input two vectore A and B.
ListNode(vector<int> array)
{
vector<int>::iterator itr = array.begin();
ListNode *t = nullptr;
for (; itr < array.end(); itr++) {
t->val = *itr;
t = t->next;
}
}
This is a strange overflow ??
#include <iostream>
#include <vector>
using namespace std;
/*
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) {}
ListNode(vector<int> array)
{
vector<int>::iterator itr = array.begin();
ListNode *t = nullptr;
for (; itr < array.end(); itr++) {
t->val = *itr;
t = t->next;
}
}
};
class Solution {
public:
Solution(){};
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode *p = l1;
ListNode *q = l2;
ListNode *dummyHead = new ListNode(0);
ListNode *current = dummyHead;
int carry = 0;
while (p != NULL || q != NULL) {
int x = (p != NULL) ? p->val : 0;
int y = (q != NULL) ? q->val : 0;
int sum = carry + x + y;
carry = sum / 10;
current->next = new ListNode(sum % 10);
current = current -> next;
if (p != NULL) {
p = p -> next;
}
if (q != NULL) {
q = q -> next;
}
}
if (carry > 0) {
current -> next = new ListNode(carry);
}
return dummyHead->next;
}
};
int main(int argc, const char * argv[]) {
Solution *sol = nullptr;
vector<int> A = {2,4,3};
vector<int> B = {5,6,4};
ListNode *list1= new ListNode(A);
ListNode *list2= new ListNode(B);
sol->addTwoNumbers(list1,list2);
return 0;
}
Use case for test:
Input: l1 = [2,4,3], l2 = [5,6,4]
Output: [7,0,8]
Explanation: 342 + 465 = 807.
Your ListNode constructor is not creating a new ListNode for t to point at before you access t->val. It is also not even attempting to initialize the members of this.
Try something more like this instead:
struct ListNode {
int val = 0;
ListNode *next = nullptr;
ListNode(int x = 0, ListNode *next = nullptr) : val(x), next(next) {}
ListNode(const vector<int> &array)
{
if (!array.empty()) {
auto itr = array.begin();
val = *itr++;
ListNode **t = &next;
while (itr != array.end()) {
*t = new ListNode(*itr++);
t = &((*t)->next);
}
}
}
};
That being said, having such a constructor in ListNode really makes no sense. A list node should only care about its own data, not about the data of the nodes around it. This kind of list construction really belongs in a separate List class that wraps a chain of ListNodes, eg:
#include <iostream>
#include <vector>
#include <utility>
/*
Definition for singly-linked list.
*/
struct ListNode {
int val = 0;
ListNode *next = nullptr;
ListNode(int x = 0, ListNode *next = nullptr) : val(x), next(next) {}
};
class List {
private:
ListNode *head = nullptr;
public:
List() = default;
List(const vector<int> &vec)
{
ListNode **t = &head;
for (int val : vec) {
*t = new ListNode(val);
t = &((*t)->next);
}
}
List addNumber(const List &l) const {
ListNode *p = head;
ListNode *q = l.head;
List dummyList;
ListNode** current = &(dummyList.head);
int carry = 0;
while (p || q) {
int x = (p) ? p->val : 0;
int y = (q) ? q->val : 0;
int sum = carry + x + y;
carry = sum / 10;
*current = new ListNode(sum % 10);
current = &((*current)->next);
if (p) {
p = p->next;
}
if (q) {
q = q->next;
}
}
if (carry > 0) {
*current = new ListNode(carry);
}
return dummyList;
}
// what follows is stuff needed for compliance with the "Rule of 3/5/0":
// https://en.cppreference.com/w/cpp/language/rule_of_three
List(const List &list)
{
ListNode **t = &head;
for(ListNode *n = list.head; n; n = n->next) {
*t = new ListNode(n->val);
t = &((*t)->next);
}
}
List(List &&list)
{
std::swap(head, list.head);
}
~List()
{
ListNode *n;
for (ListNode *t = head; t; t = n) {
n = t->next;
delete t;
}
}
List& operator=(List rhs) {
List temp(std::move(rhs));
std::swap(head, temp.head);
return *this;
}
};
class Solution {
public:
List addTwoNumbers(const List &l1, const List &l2) {
return l1.addNumber(l2);
}
};
int main(int argc, const char * argv[]) {
Solution sol;
vector<int> A = {2,4,3};
vector<int> B = {5,6,4};
List list1(A);
List list2(B);
List result = sol.addTwoNumbers(list1, list2);
return 0;
}
You are dereferencing a null pointer that's why you get the memory error. You have to initialize it and allocate memory. Here you initialize ListNode *t = nullptr;. So t is referencing as NULL pointer. Next, you here dereferencing t->val = *itr; but t is pointing to NULL.
Try something like this for singly-linked list.
struct ListNode {
int val;
ListNode *next;
ListNode() : val(0), next(nullptr) {}
ListNode(int x) : val(x), next(nullptr) {}
};
Then your main task is to create a link list from a vector, for this you can use a class that holds the vector link list. And another requirement is to add to the vector link list. So we can create a vector link list in reverse order. And for this, you can use this code snippet.
class VectorList {
public:
ListNode *root;
VectorList() : root(nullptr){}
VectorList(vector<int> &array){
root = new ListNode();
ListNode *curr;
curr = root;
int _size = array.size();
for(int i = _size - 1; i >= 0; i--){
ListNode *t = new ListNode(array[i]);
curr->next = t;
curr = curr->next;
}
root = root->next;
}
};
So now we can create two vector lists and then add the vector lists and print the desired answer. And for this, you can use this code snippet.
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode* curr, *root = NULL;
int carry = 0;
while(l1 || l2){
if(l1 != NULL && l2 != NULL){
ListNode* t = new ListNode;
t->val = (l1->val + l2->val + carry) % 10;
t->next = NULL;
carry = (l1->val + l2->val + carry) / 10;
if(root == NULL){
curr = root = t;
}
else{
curr->next = t;
curr = curr->next;
}
l1 = l1->next;
l2 = l2->next;
}
else if(l1 == NULL){
ListNode* t = new ListNode;
t->val = (l2->val + carry) % 10;
t->next = NULL;
carry = (l2->val + carry) / 10;
if(root == NULL){
curr = root = t;
}
else{
curr->next = t;
curr = curr->next;
}
l2 = l2->next;
}
else if(l2 == NULL){
ListNode* t = new ListNode;
t->val = (l1->val + carry) % 10;
t->next = NULL;
carry = (l1->val + carry) / 10;
if(root == NULL){
curr = root = t;
}
else{
curr->next = t;
curr = curr->next;
}
l1 = l1->next;
}
}
if(carry){
ListNode* t = new ListNode;
t->val = carry;
t->next = NULL;
curr->next = t;
}
return root;
}
void print(ListNode *root){
ListNode *curr = root;
while(curr){
cout << curr->val << " ";
curr = curr->next;
}
cout << endl;
}
};
So overall, here is the main code with the desired output.
#include <iostream>
#include <vector>
using namespace std;
/*
Definition for singly-linked list.
*/
struct ListNode {
int val;
ListNode *next;
ListNode() : val(0), next(nullptr) {}
ListNode(int x) : val(x), next(nullptr) {}
};
class VectorList {
public:
ListNode *root;
VectorList() : root(nullptr){}
VectorList(vector<int> &array){
root = new ListNode();
ListNode *curr;
curr = root;
int _size = array.size();
for(int i = _size - 1; i >= 0; i--){
ListNode *t = new ListNode(array[i]);
curr->next = t;
curr = curr->next;
}
root = root->next;
}
};
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode* curr, *root = NULL;
int carry = 0;
while(l1 || l2){
if(l1 != NULL && l2 != NULL){
ListNode* t = new ListNode;
t->val = (l1->val + l2->val + carry) % 10;
t->next = NULL;
carry = (l1->val + l2->val + carry) / 10;
if(root == NULL){
curr = root = t;
}
else{
curr->next = t;
curr = curr->next;
}
l1 = l1->next;
l2 = l2->next;
}
else if(l1 == NULL){
ListNode* t = new ListNode;
t->val = (l2->val + carry) % 10;
t->next = NULL;
carry = (l2->val + carry) / 10;
if(root == NULL){
curr = root = t;
}
else{
curr->next = t;
curr = curr->next;
}
l2 = l2->next;
}
else if(l2 == NULL){
ListNode* t = new ListNode;
t->val = (l1->val + carry) % 10;
t->next = NULL;
carry = (l1->val + carry) / 10;
if(root == NULL){
curr = root = t;
}
else{
curr->next = t;
curr = curr->next;
}
l1 = l1->next;
}
}
if(carry){
ListNode* t = new ListNode;
t->val = carry;
t->next = NULL;
curr->next = t;
}
return root;
}
void print(ListNode *root){
ListNode *curr = root;
while(curr){
cout << curr->val << " ";
curr = curr->next;
}
cout << endl;
}
};
int main(int argc, const char * argv[]) {
Solution *sol = nullptr;
vector<int> A = {2,4,3};
vector<int> B = {5,6,4};
VectorList list1 = VectorList(A);
VectorList list2 = VectorList(B);
ListNode *root = sol->addTwoNumbers(list1.root, list2.root);
sol->print(root);
return 0;
}
Sample Input:
l1 = [2,4,3], l2 = [5,6,4]
Sample Output:
[7 0 8]
Struggling to understand why newLL is remaining as a null pointer in the following code (Line 30: Char 16: runtime error: member access within null pointer of type 'struct ListNode' (solution.cpp)) while temp0 is behaving as expected. Thank you for the help.
Problem:
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 contain a single digit. Add the two numbers and return it as a linked list. You may assume the two numbers do not contain any leading zero, except the number 0 itself.
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode *temp0 = NULL;
ListNode *temp1 = l1;
ListNode *temp2 = l2;
//keep track of head
ListNode *newLL = temp0;
int x, y, z, f;
//sum val's and create new nodes on newLL, until l1 or l2 hits a null
while(temp1 != NULL && temp2 != NULL){
x = temp1->val;
y = temp2->val;
z = x + y;
temp0 = new ListNode(z);
cout << temp0->val << endl; //no error
cout << newLL->val << endl; //error
temp0 = temp0->next;
temp1 = temp1->next;
temp2 = temp2->next;
//concatenate the rest of l1 or l2 onto newLL
if (temp1 == NULL){
while (temp2 != NULL){
y = temp2->val;
temp0 = new ListNode(y);
temp0 = temp0->next;
temp2 = temp2->next;
}
}
if (temp2 == NULL){
while (temp1 != NULL){
x = temp1->val;
temp0 = new ListNode(x);
temp0 = temp0->next;
temp1 = temp1->next;
}
}
}
//loop through and for all numbers > 9, carry the digit
temp0 = newLL;
int r,d;
while (temp0 != NULL) {
if (temp0->val > 9){
d = temp0->val / 10;
r = temp0->val % 10;
temp0->val = d;
temp0 = temp0->next;
temp0->val += r;
} else {
temp0 = temp0->next;
}
}
//return newLL
return newLL;
}
};
Here is my code for "Merge Two Sorted Lists" algorithm problem on Leetcode:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
ListNode *dummy, *pre;
dummy->next = l1;
pre = dummy;
while(l1 != NULL & l2 != NULL) {
if(l1->val < l2->val) {
pre = l1;
l1 = l1->next;
} else {
pre->next = l2;
l2->next = l1;
pre = l2;
l2 = l2->next;
}
}
if(l2 != NULL) {
pre->next = l2;
}
return dummy->next;
}
};
And I got a Runtime Error. But what is wrong with my code?
I believe that a correct implementation will require substantially more code than what you had in the OP. Here is a correct implementation which you can try. I assume that the input lists l1 and l2 are sorted in descending order (i.e. largest to smallest from head to tail).
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
ListNode *pnt1 = l1;
ListNode *pnt2 = l2;
ListNode *head;
// assign the head pointer to larger head of the two input lists
if (l1->val > l2->val) {
head = l1;
}
else {
head = l2;
}
// walk through both lists sequentially,
// and splice together the sorted list
while (pnt1->next != NULL & pnt2->next != NULL) {
if(pnt2->val > pnt1->next->val && pnt1->val > pnt2->val) {
ListNode* next = pnt1->next;
pnt1->next = pnt2;
pnt1 = next;
}
else if(pnt2->val > pnt1->next->val && pnt1->val <= pnt2->val) {
ListNode* next = pnt2->next;
pnt2->next = pnt1;
pnt2 = next;
}
else if(pnt2->val <= pnt1->next->val && pnt1->val > pnt2->val) {
pnt1 = pnt1->next;
}
}
// handle edge case where end of one or two list(s) has been reached
if (pnt1->next == NULL && pnt2->next == NULL) {
if (pnt1->val > pnt2->val) {
pnt1->next = pnt2;
}
else {
pnt2->next = pnt1;
}
}
else if (pnt1->next == NULL) {
while (pnt2->next != NULL) {
if (pnt1->val > pnt2->next->val) {
ListNode* next = pnt2->next;
pnt2->next = pnt1;
pnt1->next = next;
break;
}
pnt2 = pnt2->next;
}
if (pnt2->next == NULL) {
pnt2->next = pnt1;
}
}
else if (pnt2->next == NULL) {
while (pnt1->next != NULL) {
if (pnt2->val > pnt1->next->val) {
ListNode* next = pnt1->next;
pnt1->next = pnt2;
pnt2->next = next;
break;
}
pnt1 = pnt1->next;
}
if (pnt1->next == NULL) {
pnt1->next = pnt2;
}
}
return head;
}
};
I think you got Segmentation Fault(Core Dump) because you are trying to access the memory that is not valid:
dummy->next = l1;
You should allocate memory to the *dummy and *pre before accessing their members.
Also use &&(logical operator) instead of &(bitwise operator) in the loop. Replace:
while(l1 != NULL & l2 != NULL) {
with
while(l1 != NULL && l2 != NULL) {
Use new operator to allocate memory and please use delete to free the same and avoid memory leaks.
Also note that the implementation itself is faulty by logic. Please refer here for better implementations.
Here is a simple recursive implementation:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
{
ListNode* result = NULL;
/* Base cases */
if (l1 == NULL)
return (l2);
else if (l2 == NULL)
return (l1);
if (l1->data <= l2->data)
{
result = l1;
result->next = mergeTwoLists(l1->next, l2);
}
else
{
result = l2;
result->next = mergeTwoLists(l1, l2->next);
}
return(result);
}
The main problem in your code is that you are using:
dummy->next = l1;
when dummy has not been initialized to point to a valid object.
You are also using a bitwise & where a logical && is appropriate.
while(l1 != NULL & l2 != NULL) {
Here's a suggested implementation.
PS It's not been tested but it looks correct to me.
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
ListNode* ret = NULL;
ListNode* pre = NULL;
// Make sure the start of the list to be returned points to the right
// ListNode.
if ( l1 != NULL && l2 != NULL )
{
if ( l1->val < l2->val )
{
ret = l1;
l1 = l1->next;
}
else
{
ret = l2;
l2 = l2->next;
}
}
else if ( l1 != NULL )
{
return l1;
}
else
{
return l2;
}
pre = ret;
while(l1 != NULL && l2 != NULL) {
// Figure out where pre->next must point to.
// Advance l1 and l2 appropriately.
if(l1->val < l2->val) {
pre->next = l1;
pre = l1;
l1 = l1->next;
} else {
pre->next = l2;
pre = l2;
l2 = l2->next;
}
}
// Make sure pre->next points to the remaining ListNodes.
// They could be in l1 or l2.
if ( l1 != NULL )
{
pre->next = l1;
}
if( l2 != NULL)
{
pre->next = l2;
}
return ret;
}
In addition to the problems already pointed out, the original code doesn't handle the case where the end of list 2 is reached first, in which case, the remainder of list 1 should be appended to the merged list. Using a pointer to pointer (instead of a previous pointer) makes the code simpler. Here is example code to merge two lists and also a bottom up merge sort that uses the merge lists function. The sort uses an array of pointers to lists, where array[i] is either null or it points to a list with pow(2,i) elements in it.
ListNode * MergeLists(ListNode *pl1, ListNode *pl2)
{
ListNode *plm = NULL; /* merged list head ptr */
ListNode **pplm = &plm; /* ptr to head or prev->next */
if(pl1 == NULL)
return pl2;
if(pl2 == NULL)
return pl1;
while(1){
if(pl2->val < pl1->val){ /* if src2 < src1 */
*pplm = pl2;
pl2 = *(pplm = &(pl2->next));
if(pl2 == NULL){
*pplm = pl1;
break;
}
} else { /* src1 <= src2 */
*pplm = pl1;
pl1 = *(pplm = &(pl1->next));
if(pl1 == NULL){
*pplm = pl2;
break;
}
}
}
return plm;
}
#define NUMLISTS 32 /* number of lists */
ListNode * SortList(ListNode *pList)
{
ListNode * aList[NUMLISTS]; /* array of lists */
ListNode * pNode;
ListNode * pNext;
int i;
if(pList == NULL) /* check for empty list */
return NULL;
for(i = 0; i < NUMLISTS; i++) /* zero array */
aList[i] = NULL;
pNode = pList; /* merge nodes into aList[] */
while(pNode != NULL){
pNext = pNode->next;
pNode->next = NULL;
for(i = 0; (i < NUMLISTS) && (aList[i] != NULL); i++){
pNode = MergeLists(aList[i], pNode);
aList[i] = NULL;
}
if(i == NUMLISTS)
i--;
aList[i] = pNode;
pNode = pNext;
}
pNode = NULL; /* merge array into one list */
for(i = 0; i < NUMLISTS; i++)
pNode = MergeLists(aList[i], pNode);
return pNode;
}
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;
}