21 | Merge Two Sorted Lists | 40.10% | 结合两个listnode,按照从小到大依次对比,先接小的数字 |
__init__()调用不用写函数名直接写类名; while x: =while x is not None: =while x!=None: while not x: =while x is None: =while x==None: 可变对象: list,set,dict 不可变对象:str, int, float, tuple and 和 or 用法:并不返回布尔值,而是返回它们实际进行比较的值之一 or用法:从左到右返回第一个为真的表达式值,无真值则返回最后一个表达式值。 |
set():无序和无重复元素的集合,可用来删除重复元素,删除后要重新排序。 dict和set的key必须是不可变对象(str,int) ,不能是可变对象(list) str='abc', list=['a','b','c'] dict,list,set区别: list和set是有序的,编号从0开始,而dict是无序的; set和dict的元素不能重复,list可以重复 dict与list比较: dict内存大,查找和插入的速度极快,不会随着key的增加而变慢, dict是用空间来换取时间的一种方法; list内存占用小,查找和插入的时间随着元素的增加而增加。 |
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Thu Jan 11 14:07:09 2018
@author: vicky
"""
#__init__():
#https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001431864715651c99511036d884cf1b399e65ae0d27f7e000
# 由于类可以起到模板的作用,因此,可以在创建实例的时候,把一些我们认为必须绑定的属性强制填写进去。
#通过定义一个特殊的__init__方法,在创建实例的时候,就把value,next等属性绑上去。
# 注意:特殊方法“__init__”前后分别有两个下划线
# 注意到__init__方法的第一个参数永远是self,表示创建的实例本身,
# __init__作用:支持带参数的类的初始化、实现类本身相关内容的初始化
# python的构造和初始化:(new,init,del三种对比)http://pycoders-weekly-chinese.readthedocs.io/en/latest/issue6/a-guide-to-pythons-magic-methods.html#id2
#__new__(cls, [...) __new__ 是在一个对象实例化的时候所调用的第一个方法。
# 它的第一个参数是这个类,其他的参数是用来直接传递给 __init__ 方法。
# __new__ 方法相当不常用,但是它有自己的特性,特别是当继承一个不可变的类型比如一个tuple或者string。
# 我不希望在 __new__ 上有太多细节,因为并不是很有用处。
#
#__init__(self, […) 此方法为类的初始化方法。
# 当构造函数被调用的时候的任何参数都将会传给它。
# (比如如果我们调用 x = SomeClass(10, 'foo')),那么 __init__ 将会得到两个参数10和foo。
# __init__ 在Python的类定义中被广泛用到。
#
#__del__(self) 如果 __new__ 和 __init__ 是对象的构造器的话,那么 __del__ 就是析构器。
# 它不实现语句 del x (以上代码将不会翻译为 x.__del__() )。
# 它定义的是当一个对象进行垃圾回收时候的行为。
# 当一个对象在删除的时需要更多的清洁工作的时候此方法会很有用,比如套接字对象或者是文件对象。
#Definition for singly-linked list.
class ListNode:
def __init__(self, x): #__init__():初始化类的属性值
self.val = x #当前节点的value
self.next = None #接下来所有的节点值 why?
#print(self.val)
def display(self): #构造显示listnode的dispay函数,可以打印一整串的链表
while self is not None:
#while self:
#while self !=None:
print(self.val)
self=self.next
##__init__()的调用方法:
#t=1->3->2
t=ListNode(1) #调用时不用写函数__init__名,直接写类名ListNode(x),输入开头节点值int x=2
t.next=ListNode(3) #第二个节点值3
t.next.next=ListNode(2) #第二个节点值2
t.val #用点.来调用对象的属性,输出值为开头节点值1
t.next.display() #输出为第二个节点开始之后的节点值,3,2
t.display() #输出为1,3,2
#法1:迭代
class Solution:
def mergeTwoLists(self, l1, l2):
"""
:type l1: ListNode
:type l2: ListNode
:rtype: ListNode
"""
# python对象分为两种:http://blog.csdn.net/lluozh2015/article/details/74942329
# 可变对象:当引用对象改变时,赋值对象也同时改变,注意当对象重新赋值时是不变的
# list,set,dict
# eg:a=[1,2,3] #a,b为list
# b=a
# a[1]=3 #b变
# a=[1,2] #b不变,因为a重新赋值了
# 不可变对象:赋值对象不变
# int,float, str,tuple
p=ListNode(0) #开头节点值为0
tmp=p #listnode为可变对象,只要p的值变,t也跟着变;
while l1 and l2:
# while l1!=None and l2!=None:
if l1.val<l2.val: #当l1的开头节点值<l2的开头节点值时
#eg:第一次循环:
#l1=4->2->4->6, l1.val=4, l1.next=2->3->6
#l2=1->4->3, l2.val=1, l1.next=4->3
p.next=l1
l1=l1.next
else:
p.next=l2 #p=0,1,4,3; 1,4,3; 4,3;
l2=l2.next #l2=4,3; 3; none;
#tmp=0,1,4,3; 0143; 0143;
p=p.next #p=1,4,3; 4,3; 3;
p.next=l1 or l2 #或p.next=l1 if l1!=None else l2
#哪个不为空,就在尾部接上它。l1=4246不为空,所以p变为34246,t变为01434246
# and 和 or 执行布尔逻辑演算,并不返回布尔值,而是返回它们实际进行比较的值之一:http://blog.csdn.net/niuniuyuh/article/details/71213887
# A or B:从左到右扫描,返回第一个为真的表达式值,无真值则返回最后一个表达式值。
# A and B:从左到右扫描,返回第一个为假的表达式值,无假值则返回最后一个表达式值。
return tmp.next #去掉开头节点0
#tmp在p.next=l1和p.next=l2时改变,想当于t.next=l1或l2。在p=p.next时不变
#即一直想尾部加不重复的值,不删值
#print(l1.display())
#print(l2.display())
#print(p.display())
#print(tmp.display())
#if __name__ == "__main__":
l1 = ListNode(4) #输入l1.val,输出4
l1.next = ListNode(2) #输入l1.next.val,输出2
l1.next.next=ListNode(4) #输入l1.next.next.val,输出4
l1.next.next.next=ListNode(6)
#l1.display()
l2 = ListNode(1)
l2.next = ListNode(4)
l2.next.next = ListNode(3)
ans = Solution().mergeTwoLists(l1,l2)
print("Final result:" )
ans.display()
#法2:递归,难理解
class Solution:
def mergeTwoLists(self, l1, l2):
"""
:type l1: ListNode
:type l2: ListNode
:rtype: ListNode
"""
if l1==None or l2==None:
return l1 or l2 #返回非空的那一个
if l1.val<l2.val: #如果l1开头节点更小,则以l1开头,接下来是l1和l2开头中的最小值
l1.next=self.mergeTwoLists(l1.next, l2)
return l1
else:
l2.next=self.mergeTwoLists(l1, l2.next)
return l2
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sat Jan 13 17:59:15 2018
@author: vicky
"""
#https://sodaoo.github.io/2017/11/28/LeetCode-21/
# 定义节点 ,用来测试
class ListNode:
def __init__(self, x):
self.val = x
self.next = None
def display(self): # 可以打印一整串的链表哦
while self !=None:
print(self.val)
self = self.next
class Solution:
def mergeTwoLists(self, l1, l2):
temp = current = ListNode(0)
while l1 and l2: # O(min(m,n))
if l1.val < l2.val:
current.next = l1
l1 = l1.next
else: # l1.val >= l2.val
current.next = l2
l2 = l2.next
current = current.next
# 那个不为空 就在尾部接上它.
current.next = l1 or l2
return temp.next
# 主函数测试
a = ListNode(1)
a.next = ListNode(4)
a.next.next = ListNode(3)
#a.next.next.next = ListNode(17)
b = ListNode(4)
b.next = ListNode(2)
b.next.next = ListNode(4)
b.next.next.next = ListNode(6)
#b.next.next.next.next = ListNode(222)
te = Solution()
res = te.mergeTwoLists(b,a)
print("Final result:" )
res.display()