Add Two Numbers
|問題説明|
空のリンクリストが2つあります.
各リストでは、自然数と0が逆順序で関連付けられています.
2つのリンク・リストの値を含む新しいリンク・リストを返します.
このとき一番前の位置は0ではありません.
> Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
> Output: 7 -> 0 -> 8
> Explanation: 342 + 465 = 807.
Input
ListNode* l1
ListNode* l2
Output
ListNode*
||トラブルシューティング|
ListNode* answer;
1) O(n)-アップロードできるか?
-2つのリンクリストが終了するまでwhileゲートを返します.
-まず、リンクリストが閉じられているかどうかを確認し、まだ閉じていない場合は、各リストのvalを追加し、%10を使用して残りの((v 1+v 2+upper)を新しいリスト(tmp)のvalにのみ保存します.
-(l 1->val+l 2->val)/10は1か0かを判断し、上に1か0を入れる.
-l 1、l 2をそれぞれ次の接続に変換します.
-tmpの位置もtmp->nextに変更されます.
|コード|
[20.0.10.01]失敗
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode* answer, *tmp;
int upper = 0, e1 = 0, e2 = 0;
answer = tmp;
while(1) {
int v1 = 0, v2 = 0;
// l1, l2의 종료 여부 판단
if(!e1) {
if(l1 != nullptr) v1 = l1->val;
else e1 = 1;
}
if(!e2) {
if(l2 != nullptr) v2 = l2->val;
else e2 = 1;
}
if(e1 + e2 == 2) break;
// l1 + l2
tmp->val = (v1 + v2 + upper) % 10;
if((l1->val + l2->val) / 10) upper = 1;
else upper = 0;
// 다음 위치로 이동
tmp = tmp->next;
l1 = l1->next;
l2 = l2->next;
}
return answer;
}
};
ListNode(tmpを除く)に回答し、新しいListNode(メモリ不足→ダイナミックメモリ割り当て)を使用してアドレスエラーを解決[20.0.10.01]失敗
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode* answer = NULL, * tmp;
int carry = 0, v = 0;
bool e1 = false, e2 = false;
while(1) {
int v1 = 0, v2 = 0;
if(!e1) l1 != NULL ? v1 = l1->val : e1 = true;
if(!e2) l2 != NULL ? v2 = l2->val : e2 = true;
v = (v1 + v2 + carry) % 10;
ListNode * tmp1 = new ListNode(v);
carry = ((v1 + v2 + carry) / 10) ? 1 : 0;
if(e1 && e2) break; // 올림수가 존재하는지에 대한 조사
if(answer == NULL) {
answer = tmp1;
tmp = tmp1;
}
else {
tmp->next = tmp1;
tmp = tmp1;
}
if(!e1) l1 = l1->next;
if(!e2) l2 = l2->next;
}
// 마지막 올림수에 대한 덧셈
if(carry) {
ListNode * tmp1 = new ListNode(1);
tmp->next = tmp1;
}
return answer;
}
};
Input : [5], [5] | Output : [0] | Expected : [0, 1]
終了条件文の場所が無効です.
錯覚...終わった...
e 1もe 2もtrueになった瞬間が終わります.
さらに後ろに進むと、無条件v=1、carryは0で、最後のif(carry)ドアは起動しません.
[20.0.10.01]成功
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode* answer = NULL, * tmp;
int carry = 0, v = 0;
bool e1 = false, e2 = false;
while(1) {
int v1 = 0, v2 = 0;
if(!e1) l1 != NULL ? v1 = l1->val : e1 = true;
if(!e2) l2 != NULL ? v2 = l2->val : e2 = true;
if(e1 && e2) break;
v = (v1 + v2 + carry) % 10;
ListNode * tmp1 = new ListNode(v);
carry = ((v1 + v2 + carry) >= 10) ? 1 : 0;
if(answer == NULL) {
answer = tmp1;
tmp = tmp1;
}
else {
tmp->next = tmp1;
tmp = tmp1;
}
if(!e1) l1 = l1->next;
if(!e2) l2 = l2->next;
}
if(carry) {
ListNode * tmp1 = new ListNode(1);
tmp->next = tmp1;
}
return answer;
}
};
1)評価
2)時間とメモリ
[20.0.10.01]約10秒減速ver
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode* answer, * tmp = new ListNode;
int carry = 0, v = 0;
answer = tmp; // return answer; 대신 answer->next로 바뀌는 대신 while(l1 && l2)에서의 조건문이 사라짐.
// 새로운 변수에 동적할당받는 대신 바로 동적할당
while(l1 && l2) {
v = (l1->val + l2->val + carry) % 10;
carry = (l1->val + l2->val + carry) / 10;
tmp->next = new ListNode(v);
tmp = tmp->next;
l1 = l1->next;
l2 = l2->next;
}
while(l1) {
v = (l1->val + carry) % 10;
carry = (l1->val + carry) / 10;
tmp->next = new ListNode(v);
tmp = tmp->next;
l1 = l1->next;
}
while(l2) {
v = (l2->val + carry) % 10;
carry = (l2->val + carry) / 10;
tmp->next = new ListNode(v);
tmp = tmp->next;
l2 = l2->next;
}
if(carry) tmp->next = new ListNode(1);
return answer->next;
}
};
Reference
この問題について(Add Two Numbers), 我々は、より多くの情報をここで見つけました https://velog.io/@yerin6860/Add-Two-Numbersテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol