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;
        }
    };