ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [LeetCode] Add Two Numbers
    코딩테스트/LeetCode 2022. 1. 2. 17:13

    문제

    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.

    두 개의 음이 아닌 정수를 나타내는 비어 있지 않는 linked-list가 주어진다. 숫자는 역순으로 저장되고 각 노드에는 단일 숫자가 포함된다. 두 숫자를 더하고 linked-list로 합을 반환한다. 두 숫자에 숫자 0 자체를 제외하고는 선행 0이 포함되어 있지 않다고 가정한다.
    => 두 linked-list 의 합을 구한다. 각 노드는 단일 숫자(0~9)이기 때문에 다음 노드로 올림 처리를 해줘야 한다.

     

    Example

    Example 1:
    Input: l1 = [2,4,3], l2 = [5,6,4]
    Output: [7,0,8]
    Explanation: 342 + 465 = 807.


    Example 2:

    Input: l1 = [0], l2 = [0]
    Output: [0]


    Example 3:

    Input: l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
    Output: [8,9,9,9,0,0,0,1]

     

    Constraints:

    • The number of nodes in each linked list is in the range [1, 100].
    • 0 <= Node.val <= 9
    • It is guaranteed that the list represents a number that does not have leading zeros.

    풀이

    /**
     * Definition for singly-linked list.
     * function ListNode(val, next) {
     *     this.val = (val===undefined ? 0 : val)
     *     this.next = (next===undefined ? null : next)
     * }
     */
    /**
     * @param {ListNode} l1
     * @param {ListNode} l2
     * @return {ListNode}
     */
    var addTwoNumbers = function(l1, l2) {
      const arrayL1 = convertListNodeToArray(l1);
      const arrayL2 = convertListNodeToArray(l2);
      const sum = sumArray(arrayL1, arrayL2);
      return convertArrayToListNode(sum.reverse());
    };
    
    function convertListNodeToArray(listNode) {
      const array = [listNode.val];
      
      while(listNode.next !== null){
          listNode = listNode.next;
          array.push(listNode.val)
      }
      
      return array;
    }
    
    function sumArray(array1, array2) {
      const newArray = [];
      const length = array1.length > array2.length ? array1.length : array2.length;
      let extra = 0;
      
      for(let i = 0; i < length; i++) {
        const value = (array1[i] || 0) + (array2[i] || 0) + extra;
        extra = Math.floor(value / 10);
        newArray[i] = value % 10;
      }
      
      if (extra > 0) {
        newArray[newArray.length] = extra;
      }
      
      return newArray;
    }
    
    function convertArrayToListNode(array) {
      return array.reduce((acc, curr) => {
        if (acc == null) {
          acc = new ListNode(curr);
    
        } else {
          acc = new ListNode(curr, acc);
        }
        return acc;
      }, null);
    }

    => 생각나는대로 풀었다.

     

    • Runtime: 132ms ~ 231ms
    • Memory: 44.2MB ~ 45.5MB

     

    다른 사람 풀이

    분포율이 제일 높았던 풀이법

    /**
     * Definition for singly-linked list.
     * function ListNode(val, next) {
     *     this.val = (val===undefined ? 0 : val)
     *     this.next = (next===undefined ? null : next)
     * }
     */
    /**
     * @param {ListNode} l1
     * @param {ListNode} l2
     * @return {ListNode}
     */
    var addTwoNumbers = function(l1, l2) {
        const d = new ListNode();
        let curr = d;
        let carry = 0;
        while (l1 || l2 || carry) {
            const sum = (l1 ? l1.val : 0) + (l2 ? l2.val : 0) + carry;
            carry = sum / 10 | 0;
            curr.next = new ListNode(sum % 10);
            if (l1) l1 = l1.next;
            if (l2) l2 = l2.next;
            curr = curr.next;
        }
        return d.next;
    };

    => 내가 생각했던 로직이였는데, linked-list는 위와 같이 하면 되는 거였다.

     

    Runtime이 가장 빨랐던 풀이법

    /**
     * Definition for singly-linked list.
     * function ListNode(val, next) {
     *     this.val = (val===undefined ? 0 : val)
     *     this.next = (next===undefined ? null : next)
     * }
     */
    /**
     * @param {ListNode} l1
     * @param {ListNode} l2
     * @return {ListNode}
     */
    var addTwoNumbers = function(l1, l2) {
      return addNodeList(l1, l2);
    };
    
    /**
     * @param {ListNode} l1
     * @param {ListNode} l2
     * @param {number} extra
     * @return {ListNode}
     */
    var addNodeList = function(l1, l2, extra = 0) {
        if (l1 === null && l2 === null && extra === 0) {
            return null;
        }
        
        var n1 = l1 !== null ? l1.val : 0;
        var n2 = l2 !== null ? l2.val : 0;
        var total = n1 + n2 + extra;
        
        var digit = total % 10;
        var newExtra = (total - digit) / 10;
        var next1 = l1 !== null ? l1.next : null;
        var next2 = l2 !== null ? l2.next : null;
        
        return new ListNode(digit, addNodeList(next1, next2, newExtra));
    }

    => 재귀인건가.. 세상에나..


    결론

    알고리즘 및 코딩테스트 문제를 많이 안 풀어봐서, 기계적으로 Array로 로직을 구현하려고 했다.

    linked-list일 경우 로직 처리 방식에 대해 알 수 있었다.

    '코딩테스트 > LeetCode' 카테고리의 다른 글

    [LeetCode] Palindrome Number  (0) 2022.01.04
    [LeetCode] Longest Substring Without Repeating Characters  (0) 2022.01.03
    [LeetCode] Two Sum  (0) 2022.01.01

    댓글

Designed by Tistory.