Leetcode链表专题

Leetcode链表专题

  • Python与C链表操作对比
  • Leetcode21-剑指OFFER面试题25合并两个有序的链表
    • 思路分析
    • 代码
  • Leetcode206Reverse Linked List剑指OFFER面试题24 反转链表
    • 思路分析
    • 代码

Python与C++链表操作对比

C++判断一个节点是不是空节点的写法:

//比如:
void Doing(ListNode* pHead1)
{
    if (pHead1==nullptr)
        printf("pHead1是空指针");
}

Python判断一个节点是不是空节点的写法

#比如l1是一个节点
if(l1!=None)
#或者
if not l1 :
    pass

Leetcode21-剑指OFFER面试题25合并两个有序的链表

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.

思路分析

Leetcode链表专题_第1张图片
Leetcode链表专题_第2张图片

代码

# 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的一个属性,具体指向什么由赋值决定。

Leetcode206.Reverse Linked List/剑指OFFER面试题24 反转链表

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

你可能感兴趣的:(Leetcode)