Leetcode 2. Add Two Numbers
Leetcode 2. Add Two Numbers
这道题比较简单,主要练练手,通过这道题可以看到 leetcode 官方对于不同语言的链表的定义,了解不同语言之间的差异,特别是关于 Swift 的 nil
,var
, let
处理。
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
}
}