LeetCode刷题笔记(Python3)——2. 两数相加
(点击查看题目)(点击查看官方题解)
官方题解中这次没有直接给出可粘贴使用的Python代码,但官方的题解视频中使用的就是Python代码,可以参考。
LeetCode刷题笔记(Python3)——2. 两数相加
- 初始解法
- 优化解法:
- 1. Python的特殊赋值方法
- 2. Python中None的真假
- 3. Python运算符
- 4. 过长代码行的换行
- 简短解法:
- 5. 条件语句的两类用法
- 6. 链表的定义
- 7. 推荐使用Pycharm写代码,个人觉得比Spyder好用
- 8. Pycharm的两种常用快捷键
初始解法
# 时间复杂度:O(max(M,N)) 空间复杂度:O(max(M,N))
class Solution:
def numCarry(cur_node): # 进位函数
if cur_node.val >= 10:
cur_node.val -= 10
return 1
else:
return 0
def addOneAtEnd(cur_node): # 最高位进1函数
new_node = ListNode()
new_node.val = 1
cur_node.next = new_node
def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
flag_l1_end = 0 # l1结束标志
flag_l2_end = 0 # l2结束标志
flag_carry = 0 # 进位标志
result = ListNode()
cur_node = result
while 1:
new_node = ListNode()
cur_node.next = new_node
cur_node = new_node
if flag_l1_end: # l1已经结束
cur_node.val = l2.val + flag_carry
flag_carry = Solution.numCarry(cur_node)
if l2.next is None:
if flag_carry:
Solution.addOneAtEnd(cur_node)
return result.next
l2 = l2.next
elif flag_l2_end: # l2已经结束
cur_node.val = l1.val + flag_carry
flag_carry = Solution.numCarry(cur_node)
if l1.next is None:
if flag_carry:
Solution.addOneAtEnd(cur_node)
return result.next
l1 = l1.next
else: # l1和l2均未结束
cur_node.val = l1.val + l2.val + flag_carry
flag_carry = Solution.numCarry(cur_node)
if l1.next is None:
flag_l1_end = 1
else:
l1 = l1.next
if l2.next is None:
if flag_l1_end:
if flag_carry:
Solution.addOneAtEnd(cur_node)
return result.next
else:
flag_l2_end = 1
l2 = l2.next这个解法虽然没错,效率也不低,但由于很久不写Python代码,很多基本操作都忘记了,导致代码过于啰嗦。官方解法给出的优化解法如下。
优化解法:
# 时间复杂度:O(max(M,N)) 空间复杂度:O(max(M,N))
class Solution:
def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
head = point = ListNode() # 表头
carry = 0 # 进位
while l1 or l2:
new_node = ListNode()
if not l1: # l1已经结束
sum_ = l2.val + carry
new_node.val = sum_ % 10
carry = sum_ // 10
l2 = l2.next
elif not l2: # l2已经结束
sum_ = l1.val + carry
new_node.val = sum_ % 10
carry = sum_ // 10
l1 = l1.next
else: # l1和l2均未结束
sum_ = l1.val + l2.val + carry
new_node.val = sum_ % 10
carry = sum_ // 10
l1 = l1.next
l2 = l2.next
point.next = new_node
point = new_node
if carry: # 最高位前还需要进1
point.next = ListNode(1)
return head.next1. Python的特殊赋值方法
a = b = c = 1 # 相当于其他编程语言中的 c = 1, b = c, a = b
a, b = 1, 'hello' # 对应赋值,基本相当于其他编程语言中的 a = 1, b = 'hello'
a, b = b, a # 对应赋值的特殊用法,相当于交换变量a和b的值注意:Python中的 “a, b = b, a”之所以相当于交换变量a和b的值,是因为a = b和b = a这两个操作是同时而非顺序进行的。
2. Python中None的真假
- Python 中 0 为假,大小为 0 的容器也定义为假。所以空字符串与空的列表也为假。
- None 可作为一个对象,该对象的类型为NoneTye。None 表示的含义,更多的是一种不存在,是真正的空,而不是空列表([])的空,例如一个函数的没有返回值。
# 几个例子
not None # False
None == None # True
None is None # True
[] == None # False
[] is None # False注意:参考博客中有一处 “错误”(也可能是Python后来做了修改)。None不能与数字做比较。如果出现此类比较,如“1 > None”系统将提示
TypeError: ‘>’ not supported between instances of ‘int’ and ‘NoneType’
3. Python运算符
长时间不写Python,像“//”(整除)、“**”(幂)、“!=”(不等于)等很多基本运算符都忘记了。具体可以参考菜鸟教程:Python运算符。
# 几个例子
5 // 2 # 2
2 ** 3 # 8
1 != 2 # True注意:不等号“<>”已经被Python3废弃,应该使用“!=”替代。
4. 过长代码行的换行
在需要换行的位置使用反斜杠“\”后直接换行即可。
a = 1 + \
2 # a = 3上述代码已经是在题解中浏览到的最好的代码了。不过,如果追求代码的简洁,还可以采用下面这种更尖端的解法(并没有更快,只是更帅哈哈 😃 )。
简短解法:
# 时间复杂度:O(max(M,N)) 空间复杂度:O(max(M,N))
class Solution:
def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
cur = head = ListNode(l1.val + l2.val)
while l1.next or l2.next:
l1 = l1.next if l1.next else ListNode()
l2 = l2.next if l2.next else ListNode()
cur.next = ListNode(l1.val + l2.val + cur.val // 10)
cur.val = cur.val % 10
cur = cur.next
if cur.val >= 10:
cur.next = ListNode(cur.val // 10)
cur.val = cur.val % 10
return head5. 条件语句的两类用法
上述代码简洁的一个关键就是条件语句的另一种用法。
常见用法
if 判断条件1: # 不要忘记使用冒号
执行语句1
elif 判断条件2:
执行语句2
elif 判断条件3:
执行语句3
else:
执行语句4特殊用法
a = 1 if 判断语句 else 2此时,如果判断语句为真,则执行 a = 1;否则将执行 a = 2。
6. 链表的定义
通过系统的提示,可以学习Python中如何定义链表。
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next7. 推荐使用Pycharm写代码,个人觉得比Spyder好用
以前写Python代码全用的是Spyder,但最近用Pycharm发现Pycharm会提示很多代码规范性的东西,有助于帮助自己把代码写得更规范、清晰、易懂。
例如,如果函数用了大写字母,系统会提示“Function name should be lowercase”(函数名应该使用小写字母);如果两个函数的定义之间只间隔了一行,那么系统会提示“expected 2 blank lines”(期望有两个空行)等等。
因此,个人更倾向于推荐使用Pycharm来写代码。
8. Pycharm的两种常用快捷键
- 注释/取消注释:选中后,“Ctrl + /”。无论单行多行,都是这一个快捷键。
- 撤销/恢复:“Ctrl + z”/“Ctrl + Shift + z”。后者会与搜狗输入法中“符号大全”的快捷键冲突,建议在搜狗输入中将“符号大全”的快捷键修改为“Ctrl + Shift +x”,这样与一般的快捷键都不会冲突且改动不大。
















