leetcode HOT 21&148&236

Leetcode 21. 合并两个有序链表

难度 ⭐
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
**加粗样式**

思路

当两个链表都非空时,选链表头最小的那个添加到辅助链表中;当有一个链表为空,另一个链表非空的时候,直接一股脑塞进辅助链表。

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution(object):
    def mergeTwoLists(self, l1, l2):
        """
        :type l1: ListNode
        :type l2: ListNode
        :rtype: ListNode
        """
        head = ListNode(-1) #辅助链表头
        tmp = head #向辅助链表中插入新节点
        left_pointer = l1
        right_pointer = l2
        while(left_pointer and right_pointer): #neither of the two lists is empty
            if left_pointer.val < right_pointer.val:
                tmp.next = ListNode(left_pointer.val)
                tmp = tmp.next
                left_pointer = left_pointer.next

            else:
                tmp.next = ListNode(right_pointer.val)
                tmp = tmp.next
                right_pointer = right_pointer.next
        if left_pointer:
            while(left_pointer):
                tmp.next = ListNode(left_pointer.val)
                tmp = tmp.next
                left_pointer = left_pointer.next
        if right_pointer:
            while(right_pointer):
                tmp.next = ListNode(right_pointer.val)
                tmp = tmp.next
                right_pointer = right_pointer.next
        return head.next

✅ 总结
当需要建立一个新链表时,可以先建一个不含有任何数据的链表头head,然后再用tmp指向head,每次都向tmp.next插入数据即可

Leetcode 148. 排序链表

给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。
进阶:
你可以在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序吗?

在这里插入图片描述

思路

很自然的想到归并排序。那么我们可以用上一题的方法合并有序列表了!唯一的问题是,列表是不支持随机访问的,那么应该如何通过一次遍历找到列表的中点呢?
这里我们使用“快指针慢指针”方法。快指针从head->next出发,一次移动两格;慢指针从head出发,一次移动一格。

class Solution(object):
    def sortList(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        if not head or not head.next: #终止条件
            return head
        slow = head #慢指针
        fast = head.next #快指针
        while(fast and fast.next):
            slow = slow.next
            fast = fast.next.next
        l2_head = slow.next ##第二个列表
        slow.next = None ##截断!
        return self.mergeTwoLists(self.sortList(head),self.sortList(l2_head))
    def mergeTwoLists(self, l1, l2):
        """
        :type l1: ListNode
        :type l2: ListNode
        :rtype: ListNode
        """
        head = ListNode(-1)
        tmp = head
        left_pointer = l1
        right_pointer = l2
        while(left_pointer and right_pointer): #neither of the two lists is empty
            if left_pointer.val < right_pointer.val:
                tmp.next = ListNode(left_pointer.val)
                tmp = tmp.next
                left_pointer = left_pointer.next

            else:
                tmp.next = ListNode(right_pointer.val)
                tmp = tmp.next
                right_pointer = right_pointer.next
        if left_pointer:
            while(left_pointer):
                tmp.next = ListNode(left_pointer.val)
                tmp = tmp.next
                left_pointer = left_pointer.next
        if right_pointer:
            while(right_pointer):
                tmp.next = ListNode(right_pointer.val)
                tmp = tmp.next
                right_pointer = right_pointer.next
        return head.next

❗ 总结
快指针慢指针这个方法没有想到。

Leetcode 236. 二叉树的最近公共祖先

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先在这里插入图片描述

输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
输出:3
解释:节点 5 和节点 1 的最近公共祖先是节点 3 。

思路

很自然的想到,可以将两个节点都层层向上找parent,一直找到根节点。例如节点4对应的列表为[4,2,5,3]; 节点6对应的列表为[6,5,3]. 然后从右到左找到最后一个重合的数即可。这里,最后一个重合的数为5.
但是看到节点的定义,竟然没有parent这个值!那么怎么办呢?不要慌,用一个dict(哈希表)记录一下每个节点的parent就好了。

# Definition for a binary tree node.
class TreeNode(object):
     def __init__(self, x):
         self.val = x
         self.left = None
         self.right = None

class Solution(object):
    parent_hash = {}
    def lowestCommonAncestor(self, root, p, q):
        """
        :type root: TreeNode
        :type p: TreeNode
        :type q: TreeNode
        :rtype: TreeNode
        """
        p = p.val
        q = q.val
        stack_p = [p]
        stack_q = [q]
        self.in_traverse(root) ##得到parent哈希表
        while(p != root.val):
            stack_p.append(self.parent_hash[p])
            p = self.parent_hash[p]
        while(q != root.val):
            stack_q.append(self.parent_hash[q])
            q = self.parent_hash[q]
        print(self.parent_hash,stack_q,stack_p)
        ans = -1
        while(len(stack_q)*len(stack_p)!=0 and stack_q[-1] == stack_p[-1]):
            ans = stack_p[-1]
            stack_p = stack_p[:-1]
            stack_q = stack_q[:-1]
        return TreeNode(ans)

    def in_traverse(self,root):
        if root == None:
            return
        self.in_traverse(root.left)
        if root.left:
            self.parent_hash[root.left.val] = root.val
        if root.right:
            self.parent_hash[root.right.val] = root.val
        self.in_traverse(root.right)

❕ 总结
没有想到要用哈希表记录parent

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值