Leetcode链表专题
C++判断一个节点是不是空节点的写法:
//比如:
void Doing(ListNode* pHead1)
{
if (pHead1==nullptr)
printf("pHead1是空指针");
}
Python判断一个节点是不是空节点的写法
#比如l1是一个节点
if(l1!=None)
#或者
if not l1 :
pass
leetcode题目 21. Merge Two Sorted Lists:
Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists.
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
'''
题意:合并两个有序链表
'''
def mergeTwoLists(self, l1, l2):
dummy = ListNode(0)
tmp = dummy
while l1 != None and l2 != None:#如果链表1和链表2的头节点都不是空
if l1.val < l2.val:
tmp.next = l1
l1 = l1.next
else:
tmp.next = l2
l2 = l2.next
tmp = tmp.next
if l1 != None:#如果l1的头节点不为空,l2的头节点为空
tmp.next = l1
else:#如果l2的头节点不为空,l1的头节点为空
tmp.next = l2
return dummy.next
该解源自http://www.jiuzhang.com/solutions/merge-two-sorted-lists/
这个解法跑了52S
然后我看到最快的38S的数据,其实和52S的思路是一样的,只是while l1 and l2 还有 cur.next = l1 or l2 的写法更加精简了
## iteratively这个写法是循环的写法
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def mergeTwoLists(self, l1, l2):
"""
:type l1: ListNode
:type l2: ListNode
:rtype: ListNode
"""
dummy = cur = ListNode(0)
while l1 and l2:
if l1.val < l2.val:
cur.next = l1
l1 = l1.next
else:
cur.next = l2
l2 = l2.next
cur = cur.next
cur.next = l1 or l2
return dummy.next
##再按照书上的思路写一个递归的写法(Recursively)
##这种写法注意:就不用定义一个假的头节点dummy了
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def mergeTwoLists(self, l1, l2):
"""
:type l1: ListNode
:type l2: ListNode
:rtype: ListNode
"""
if l1==None or l2==None:#鲁棒性处理
#如果l1是空指针,l2不是空指针,则返回l2
#如果l1不是空指针,l2是空指针,则返回l1
#如果l1和l2都是空指针,则返回空指针
#如果l1和l2都不是空指针,不会进入这个循环
return l1 or l2
if l1.val < l2.val:
l1.next = self.mergeTwoLists(l1.next, l2)
return l1
else:
l2.next = self.mergeTwoLists(l1, l2.next)
return l2
这是我第一次接触LinkedList,所以自己好奇写了一些尝试代码:
class ListNode(object):
def __init__(self, x):
self.val = x
self.next = None
dummy = ListNode(0) #0是该结点的val
print(dummy)
print(dummy.val)
print(dummy.next)
输出结果是
<__main__.ListNode object at 0x0000000003F82898>
0
None
继续探索:
class ListNode(object):
def __init__(self, x):
self.val = x
self.next = None
dummy = ListNode(0)
print(dummy)
print(dummy.val)
print(dummy.next)
print("the information about second node are as fllowing:**************")
second =ListNode(5)
print(second)
print(second.val)
print(second.next)
#把dummy作为头结点连接到second
dummy.next=second
third=ListNode(8)
second.next =third
print("**************")
print (dummy.next)
print (dummy.next.val)#取出seconde结点的值
print (dummy.next.next)#取出second结点的指针域的值,如果在这之前加一句second.next=9,则此处输出9,如果加一句 third=ListNode(8) second.next =third 则输出ListNode object 具体为<__main__.ListNode object at 0x000000000495AB00>
运行结果是:
Running C:/Study/Leetcode/21MergeTwoSortedLinkedList.py<__main__.ListNode object at 0x000000000495AC50>0Nonethe information about second node are as fllowing:**************<__main__.ListNode object at 0x000000000495AB38>5None**************<__main__.ListNode object at 0x000000000495AB38>5<__main__.ListNode object at 0x000000000495AB00>
至此得出对链表结点的“深刻”理解:
dummy.next是第一个(头)结点的next域的值,因为dummy.next被赋值为second结点,所以结果指向second结点。
dummy.next.next代表第二个结点的next域的值,相当于second.next,可能是任意类型,比如数字9,或者另一个结点(third)
可以把next单纯地看作ListNode的一个属性,具体指向什么由赋值决定。
Reverse a singly linked list.
click to show more hints.
Hint:
A linked list can be reversed either iteratively or recursively. Could you implement both?
我们在调整节点i的next指针时,除了需要知道节点i本身,还需要知道i的前一个节点h,因为我们需要把节点i的Next指针指向h。同时,我们还需要事先把节点i的下一个节点j,以防止链表断开。因此,我们需要响应地定义3个指针,分别指向当前遍历到的节点(cur),它(反转前)的前一个节点(prev),它(反转前)的后一个节点(temp_next)
#注意!我个人觉得这种解法比剑指OFFER书上高明一点,因为不用额外寻找反转后链表的头节点,直接return prev,所以也就不用初始化定义pReversedHead=None
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def reverseList(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
# I use iterative method
prev=None#prev用于保存反转前的上一个节点
cur=head#cur代表当前在考虑的节点
while (cur):#如果当前节点不是空节点,则继续。对于第一次cur被赋值为head头节点时,这也是一种鲁棒性检验。即如果头节点为空,返回None
temp_next=cur.next#temp_next用于保存反转前的下一个节点
cur.next=prev#反转指针!从下一个节点指向上一个节点
prev=cur#把prev向后移动一个节点
cur=temp_next#把cur向后移动一个节点
return prev