Leetcode 2. Add Two Numbers

Leetcode 2. Add Two Numbers

这道题比较简单,主要练练手,通过这道题可以看到 leetcode 官方对于不同语言的链表的定义,了解不同语言之间的差异,特别是关于 Swift 的 nilvarlet 处理。

C++

/**
 * 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 *head = new ListNode();
        ListNode *rear = head;
        int carry = 0;
        while(l1 != nullptr || l2 != nullptr) {
            int val1 = l1 == nullptr ? 0 : l1->val;
            int val2 = l2 == nullptr ? 0 : l2->val;
            int sum = val1 + val2 + carry;
            int residue = sum % 10;
            carry = sum / 10;
            rear->next = new ListNode(residue);
            rear = rear->next;
            if(l1 != nullptr) l1 = l1->next;
            if(l2 != nullptr) l2 = l2->next;
        }

        if(carry > 0) {
            rear->next = new ListNode(carry);
        }

        return head->next;
    }
};

Ruby

# Definition for singly-linked list.
# class ListNode
#     attr_accessor :val, :next
#     def initialize(val = 0, _next = nil)
#         @val = val
#         @next = _next
#     end
# end
# @param {ListNode} l1
# @param {ListNode} l2
# @return {ListNode}
def add_two_numbers(l1, l2)
    head = rear = ListNode.new

    carry = 0
    while l1 or l2 do
        val1 = l1.nil? ? 0 : l1.val
        val2 = l2.nil? ? 0 : l2.val
        sum = val1 + val2 + carry
        residue = sum % 10
        carry = sum / 10
        rear.next = ListNode.new(residue)
        rear = rear.next

        l1 = l1.next if l1
        l2 = l2.next if l2
    end

    if carry > 0
        rear.next = ListNode.new(carry)
    end

    head.next
end

Python

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:
        head = rear = ListNode()
        carry = 0
        while l1 or l2:
            val1 = l1.val if l1 else 0
            val2 = l2.val if l2 else 0

            sum = carry + val1 + val2
            residue = sum % 10
            carry = sum // 10

            rear.next = ListNode(residue)
            rear = rear.next

            l1 = l1.next if l1 else l1
            l2 = l2.next if l2 else l2

        if carry > 0:
            rear.next = ListNode(carry)

        return head.next

Swift

涉及到 Swift Optional 处理可以单独出一片文章来介绍了,下面简单说一说。

Optional 值可能为 nil,在使用时可能会导致程序崩溃,为了应对这种情况我们通常使用 ?? 来进行判断,?? 可以类比 C++ 中的三目运算符。

var a = 10
var b: Int? = 10

var c = a + (b ?? 0)

上面的程序可以翻译为以下代码:

var c = a + (b == nil ? 0 : b!)

Swift 为了简化 Optional 处理,使用了 if let/var 语法,后续为了方便开发者又推出了 guard let语法。

func demo(x: Int?, y: Int?) {
    if let x = x, let y = y {
        print(a+b)
    } else {
        print("nil")
    }
}

func demo1(x: Int?, y: Int?) {
    guard let x = x, let y = y {
        print("x is nil or y is nil")
    } else {
        print(a+b)
    }
}

简单介绍了 Swift 的 Optional 处理,下面就可以解题了。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     public var val: Int
 *     public var next: ListNode?
 *     public init() { self.val = 0; self.next = nil; }
 *     public init(_ val: Int) { self.val = val; self.next = nil; }
 *     public init(_ val: Int, _ next: ListNode?) { self.val = val; self.next = next; }
 * }
 */
class Solution {
    
    func addTwoNumbers(_ l1:ListNode?, _ l2:ListNode?) -> ListNode? {
        let head = ListNode()
        var rear = head

        var carry = 0 //进位控制
        
        var tp1 = l1, tp2 = l2

        while tp1 != nil  ||  tp2 != nil {
            let x = tp1?.val ?? 0
            let y = tp2?.val ?? 0

            let sum = x + y + carry
            carry = sum / 10 //进位
            
            rear.next = ListNode.init(sum % 10)
            rear = rear.next!
            if tp1 != nil {
                tp1 = tp1?.next
            }
            if tp2 != nil {
                tp2 = tp2?.next
            }
            // 导致死循环  -- Why
            //tp1 = tp1?.next ?? tp1
            //tp2 = tp2?.next ?? tp2
        }
        
        if carry > 0 {//最后两数相加,如果有进位,也要加上
            rear.next = ListNode.init(carry)
        }
        
        return head.next
    }
}
posted @ 2022-05-06 11:23  Logan_Xu  阅读(31)  评论(0编辑  收藏  举报