LeetCode Python实现 链表简单部分

版权声明:转载请通过公众号《湾区人工智能》联系我授权,谢谢 https://blog.csdn.net/BTUJACK/article/details/80596285
LeetCode Python实现 链表简单部分
我以前完全没有写过关于链表的东西,
		node.val=node.next.val#当前值被后一个值覆盖
        node.next=node.next.next#下一节点跳到下下一节点

        这些关于next和val的解法从来没有见过,百度也没有搜索到,菜鸟教程也没有解释。

待我改天大脑清醒了再研究下
#2018-06-06  June Wednesday the 23 week, the 157 day SZ
'''
删除链表中的节点
请编写一个函数,使其可以删除某个链表中给定的(非末尾)节点,你将只被给定要求被删除的节点。

现有一个链表 -- head = [4,5,1,9],它可以表示为:
    4 -> 5 -> 1 -> 9


示例 1:
输入: head = [4,5,1,9], node = 5
输出: [4,1,9]
解释: 给定你链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9.


示例 2:
输入: head = [4,5,1,9], node = 1
输出: [4,5,9]
解释: 给定你链表中值为 1 的第三个节点,那么在调用了你的函数之后,该链表应变为 4 -> 5 -> 9.


说明:
•链表至少包含两个节点。
•链表中所有节点的值都是唯一的。
•给定的节点为非末尾节点并且一定是链表中的一个有效节点。
•不要从你的函数中返回任何结果。
'''

'''
方法1 
思路
直接把当前节点的值替换为下个节点的值。并把当前节点的next替换为下个节点的next
'''
# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution(object):
    def deleteNode(self, node):
        """
        :type node: ListNode
        :rtype: void Do not return anything, modify node in-place instead.
        """
        #拿到题没看懂出题意图,查了别人的答案才明白,这考点也是神奇
        node.val=node.next.val#当前值被后一个值覆盖
        node.next=node.next.next#下一节点跳到下下一节点

my_solution = Solution()
#head = [4,5,1,9]
a = my_solution.deleteNode(1)
print(a)

'''
方法2:
https://blog.csdn.net/qq_34364995/article/details/80546443
'''


'''
删除链表的倒数第N个节点
给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。

示例:
给定一个链表: 1->2->3->4->5, 和 n = 2.

当删除了倒数第二个节点后,链表变为 1->2->3->5.


说明:

给定的 n 保证是有效的。

进阶:

你能尝试使用一趟扫描实现吗?
'''

'''
方法1:
思路:需要记录有链表有几个数,并且将链表节点储存到列表里。
'''
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:  
    def removeNthFromEnd(self, head, n):  
        """ 
        :type head: ListNode 
        :type n: int 
        :rtype: ListNode 
        """  
        List = []  
        count = 0  
        while(head):  
            List.append(head)  
            head=head.next     #AttributeError: 'list' object has no attribute 'next'

            count = count+1  
          
        if count==1:  
            return None  
        if List[-n].next==None:  
            List[-n-1].next = None  
            return List[0]  
        else:  
            List[-n].val = List[-n].next.val  
            List[-n].next = List[-n].next.next  
        return List[0]

my_solution = Solution()
head = [1,2,3,4,5]
a = my_solution.removeNthFromEnd(head,2)
print(a)
'''
方法2:
思路
构建双指针p1与p2,p1先走n步,然后一同运动,当p1指向表尾,p2指向的next即是倒数第N个节点,删除即可

'''


class Solution:
    def removeNthFromEnd(self, head, n):
        """
        :type head: ListNode
        :type n: int
        :rtype: ListNode
        """
        dummy = ListNode(0) #初始节点 报错 NameError: name 'ListNode' is not defined
        dummy.next = head
        p1 = p2 = dummy
        for i in range(n):
            p1 = p1.next
        while p1.next:
            p1 = p1.next
            p2 = p2.next
        p2.next = p2.next.next
        return dummy.next


my_solution = Solution()
head = [1,2,3,4,5]
a = my_solution.removeNthFromEnd(head,2)
print(a)

'''
3
反转链表
反转一个单链表。

示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL

进阶:
你可以迭代或递归地反转链表。你能否用两种方法解决这道题?

'''
'''
方法1:
思路
对链表遍历,需保存上一个指针和下一个指针。在遍历过程中理清三者关系,注意不要互相覆盖即可。直接上代码。
'''

# 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
        """
        if head==None:
            return []
        last_temp = None
        temp = head
        while(temp!=None):
            temp_next = temp.next  #AttributeError: 'list' object has no attribute 'next'

            temp.next = last_temp
            last_temp = temp
            temp = temp_next
        
        return last_temp
my_solution = Solution()
head = [1,2,3,4,5]
a = my_solution.reverseList(head)
print(a)

'''
方法1.1:
思路
对链表遍历,需保存上一个指针和下一个指针。在遍历过程中理清三者关系,注意不要互相覆盖即可。直接上代码。
'''
# 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
        """
        if not head or not head.next:
            return head#为空或只有一个数直接返回
        curr=head;newList=None
        while curr:
            temp=curr.next#暂存curr的下一个地址
            curr.next=newList#curr.next指向这个新链表,相当于断开curr与后面的连接
            newList=curr#将当前节点赋给新链表
            curr=temp#暂存的curr.next赋给curr
        return newList

'''
方法1.3
思路一样
'''


class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None

class Solution:
    # @param {ListNode} head
    # @return {ListNode}
    def reverseList(self, head):
        if head == None:
            return head
        pre = head
        cur = head.next
        while cur != None:
            pre.next = cur.next
            cur.next = head
            head = cur
            cur = pre.next

        return head

s = Solution()

head = ListNode(0);
cur = head
for i in range(1, 10):
    node = ListNode(i)
    cur.next = node
    cur = node

head = s.reverseList(head);
while(head != None):
    print(head.val, end=' ')
    head = head.next


'''
4
合并两个有序链表
将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 

示例:
输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4
'''

#方法1 :递归
class Solution:
    def mergeTwoLists(self, l1, l2):
        """
        :type l1: ListNode
        :type l2: ListNode
        :rtype: ListNode
        """
        if l1==None and l2==None:
            return None
        if l1==None:
            return l2
        if l2==None:
            return l1
        if l1.val<=l2.val:
            l1.next=self.mergeTwoLists(l1.next,l2)
            return l1
        else:
            l2.next=self.mergeTwoLists(l1,l2.next)
            return l2

#方法2:非递归
class Solution:
    def mergeTwoLists(self, l1, l2):
        """
        :type l1: ListNode
        :type l2: ListNode
        :rtype: ListNode
        """
        head = ListNode(0)
        first = head
        while l1!=None and l2!=None:
            if l1.val <= l2.val:
                head.next = l1
                l1 = l1.next
            else:
                head.next = l2
                l2 = l2.next
            head = head.next
        if l1 != None:
            head.next = l1
        elif l2 != None:
            head.next = l2
        return first.next


#方法3


class ListNode:

    def __init__(self, x):

        self.val = x

        self.next = None

 

class Solution:

    def mergeTwoLists(self, l1, l2):

        """

        :type l1: ListNode

        :type l2: ListNode

        :rtype: ListNode

        """

        newHead = ListNode(0)

        pre = newHead

        while l1 and l2:

            if l1.val<l2.val:

                pre.next = l1

                l1 = l1.next

            else:

                pre.next = l2

                l2 = l2.next

            pre = pre.next

        if l1:

            pre.next = l1

        elif l2:

            pre.next = l2

        return newHead.next

         

# 有序链表

head1 = ListNode(2)

n1 = ListNode(3)

n2 = ListNode(4)

n3 = ListNode(9)

head1.next = n1

n1.next = n2

n2.next = n3

 

# 有序链表

head2 = ListNode(3)

m1 = ListNode(5)

m2 = ListNode(7)

m3 = ListNode(8)

head2.next = m1

m1.next = m2

m2.next = m3

 

s = Solution()

res = s.mergeTwoLists(head1,head2)

while res:

    print(res.val)

    res = res.next


'''
5
回文链表
请判断一个链表是否为回文链表。

示例 1:
输入: 1->2
输出: false

示例 2:
输入: 1->2->2->1
输出: true
进阶:
 你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?
'''
#方法1
# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution(object):
    def isPalindrome(self, head):
        """
        :type head: ListNode
        :rtype: bool
        """
        #复杂度满足要求,空间复杂度为O(n),不满足进阶要求
        if not head:
            return True
        cur=head
        array=[]
        while cur:
            array.append(cur.val)
            cur=cur.next
        return array==array[::-1]



'''
6
环形链表
给定一个链表,判断链表中是否有环。

进阶:
 你能否不使用额外空间解决此题?
'''
方法1:
# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution(object):
    def hasCycle(self, head):
        """
        :type head: ListNode
        :rtype: bool
        """
        if not head:
            return False
        p1=p2=head#p1每次跑1步,p2每次跑2步
        while p2.next and p2.next.next:#判断跑得快的是否为空
            p1=p1.next
            p2=p2.next.next
            if p1==p2:#存在环则必然会出现相等
                return True
        return False

#方法2:
思路:
快慢指针技巧,slow指针和fast指针开始同时指向头结点head,fast每次走两步,slow每次走一步。如果链表不存在环,那么fast或者fast.next会先到None。
如果链表中存在环路,则由于fast指针移动的速度是slow指针移动速度的两倍,所以在进入环路以后,两个指针迟早会相遇,如果在某一时刻slow==fast,说明链表存在环路。
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    # @param head, a ListNode
    # @return a boolean
    def hasCycle(self, head):
        if head == None or head.next == None:
            return False
        slow = fast = head
        while fast and fast.next:
            slow = slow.next
            fast = fast.next.next
            if slow == fast:
                return True
        return False

展开阅读全文

没有更多推荐了,返回首页