七10、反转和合并链表、 链表有环的判断


「@Author:Runsen」node

编程的本质来源于算法,而算法的本质来源于数学,编程只不过将数学题进行代码化。「---- Runsen」git

最近在从新梳理学算法的知识,本文为链表常见操做复习的总结文章,会讲解常见的链表题目实现思路及附上答案,这些题目在leetcode上对应的题号也有给出,好好学习算法吧~github

  • 单链表反转
  • 链表中环的检测
  • 两个有序的链表合并
  • K个有序的链表合并

leetcode 对应题号:206,141,21,23web

LeetCode 第 206 题:反转链表

反转一个单链表。面试

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

题目不难,定义三个变量pre、cur、cur.next,分别记录上一个结点,当前结点、下一个结点。算法

反转一个单链表须要当前节点的next指针指向上一个结点pre,当前节点的指针指向下一个结点,上一个结点的指针指向当前节点。编程

经过迭代,依次反转结点指向。具体代码以下小程序

class Solution:
    def reverseList(self, head):
        cur, prev = head, None
        while cur:
            cur.next, prev, cur = prev, cur, cur.next
        return prev

LeetCode 第 141 题:判断链表中是否有环

遍历整个数组, 给出的数据包含在集合中则说明有环, 返回 True; 若遍历完毕, 则说明无环, 返回 False,若是用列表也是同样。数组

「暴力解法」微信

class Solution:
    def hasCycle(self, head: ListNode) -> bool:
        """
        暴力法:经过遍历链表,用set来存储访问的节点,若是在set出现同样的节点,说明有坏,时间复杂度O(n)
        :type head: ListNode
        :rtype: bool
        """

        st = set()
        while head:
            if head in st:
                return True
            st.add(head)
            head = head.next
        return False


      # 下面是列表
        l = []
        while head:
            if head in l:
                return True
            else:
                l.append(head)
                head = head.next
        return False   

从头遍历到尾,发现指向null,说明没环。这明显不靠谱。暴力的时间空间复杂度都是O(n)

题目要求用 空间复杂度。其实,这道题考的是「快慢指针」 空间复杂度

经过使用具备 不一样速度 的快、慢两个指针遍历链表,空间复杂度能够被下降至 。慢指针每次移动一步,而快指针每次移动两步。

若是列表中不存在环,最终快指针将会最早到达尾部,此时咱们能够返回 false。

能够想象这样一个场景, 你和一个朋友一块儿散步, 你每次移动两步, 朋友每次一步, 如为单向定长道路, 你必然先到达重点. 如果环绕操场,则大家终将相遇.

class Solution(object):
    def hasCycle(self, head):
        slow = fast = head
        while slow and fast and fast.next:
            slow = slow.next
            fast = fast.next.next
            if slow == fast:
                return True
        return False

LeetCode  第21题:合并两个有序链表

将两个升序链表合并为一个新的 升序 链表并返回。新链表是经过拼接给定的两个链表的全部节点组成的。

示例: 

输入:1->2->41->3->4
输出:1->1->2->3->4->4

从两链表第一个结点开始比较结点的值,取较小者做为合并链表的元素,依次进行;后面若是有一个链表为空,则直接把不为空的链表接到合并链表的后面。

这个解决的方法使用递归,若是L1为空就返回L2,L2为空返回L1,L1的val<=L2的val,那么继续递归。

# Definition for singly-linked list.
# class ListNode:
#     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
  """

  #递归的结束点就是L1或者L2为空就返回
  #若是L1为空就返回L2,L2为空返回L1
  # if not (l1 and l2):
   # return l1 if l1 else l2
  if not l1:
            return l2
        elif not l2:
            return l1
  #L1的val<=L2的val,那么继续递归
  #当前L1的next指向一个递归函数
  #意思是L1的下一个和L2哪一个大,就做为当前L1的next
   elif l1.val<=l2.val:
   l1.next = self.mergeTwoLists(l1.next,l2)
   return l1
  else:
   l2.next = self.mergeTwoLists(l1,l2.next)
   return l2

递归的代码看起来是十分简洁的

LeetCode 第 23 题:合并 k 个排序链表

合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。

示例: 
输入:
[
 1->4->5,
 1->3->4,
 2->6
]
输出: 1->1->2->3->4->4->5->6 

第一种法就是常规暴力思路,直接将全部的元素取出,而后排个序,再重组就达到了目的。

遍历全部链表,将全部节点的值放到一个数组中。将这个数组排序,而后遍历全部元素获得正确顺序的值。用遍历获得的值,建立一个新的有序链表。

时间复杂度: ,其中 N 是节点的总数目

空间复杂度:

排序花费 空间(这取决于你选择的算法)。建立一个新的链表花费 的空间。

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None


class Solution:
    def mergeKLists(self, lists: List[ListNode]) -> ListNode :
        """
        :type lists: List[ListNode]
        :rtype: ListNode
        """

        self.nodes = []
        head = point = ListNode(0)
        for l in lists:
            while l:
                self.nodes.append(l.val)
                l = l.next
        for x in sorted(self.nodes):
            point.next = ListNode(x)
            point = point.next
        return head.next

「人生最重要的不是所站的位置,而是心里所朝的方向。只要我在每篇博文中写得本身体会,修炼身心;在天天的不断重复学习中,耐住寂寞,练就真功,不畏艰难,奋勇前行,不忘初心,砥砺前行,人生定会有所收获,不留遗憾 (做者:Runsen )」

本文已收录 GitHub,传送门~[1] ,里面更有大厂面试完整考点,欢迎 Star。



Reference

[1]

传送门~: https://github.com/MaoliRUNsen/runsenlearnpy100


更多的文章

点击下面小程序



- END -

本文分享自微信公众号 - Python之王(sen13717378202)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。

相关文章
相关标签/搜索