刷题日记

leetcode刷题总结


一、并查集

在这里插入图片描述

代码如下(示例):

class Solution:
    def findRedundantConnection(self, edges: List[List[int]]) -> List[int]:
        #顶点与边
        nodesCount =len(edges);
        parent =list(range(nodesCount+1));

        #并查集  父节点
        def find(index :int)->int:
        #父节点
            if parent[index]!=index:
                parent[index]=find(parent[index]);
            return parent[index];
        
        def union(index1:int ,index2:int):
        #index1---index2
            parent[find(index1)]=find(index2);

        for node1 ,node2 in edges:
            if find(node1)!=find(node2):
                union(node1 ,node2);
            else:
                return [node1 ,node2];
        return [];
#并查集
class UnionFind:
    def __init__(self):
        self.father = {}
        self.size_of_set = {}
    
    def get_size_of_set(self,x):
        """
        获取所在连通块的大小
        """
        return self.size_of_set[self.find(x)]
    
    def find(self,x):
        root = x      
        while self.father[root] != None:
            root = self.father[root]      
        # 路径压缩
        while x != root:
            original_father = self.father[x]
            self.father[x] = root
            x = original_father        
        return root
    
    def is_connected(self,x,y):
        return self.find(x) == self.find(y)
    
    def merge(self,x,y):
        root_x,root_y = self.find(x),self.find(y)
        
        if root_x != root_y:
        #root_x---root_y
            self.father[root_x] = root_y
            # 更新根节点连通块数量
            self.size_of_set[root_y] += self.size_of_set[root_x]
            del self.size_of_set[root_x]
    
    def add(self,x):
        if x not in self.father:
            self.father[x] = None
            self.size_of_set[x] = 1

二、二叉树

代码如下(示例):

#遍历方式
#先序遍历:
#中 ----右
def dfs(root):
    if not root:
        return
    执行操作
    dfs(root.left)
    dfs(root.right)
#中序遍历:
# 左----右
def dfs(root):
    if not root:
        return
    dfs(root.left)
    执行操作
    dfs(root.right)
#或单纯遍历
class Solution:
    def inorderTraversal(self, root: TreeNode) -> List[int]:
        if not root:
            return [];
        return self.inorderTraversal(root.left)+[root.val]+self.inorderTraversal(root.right);
#后序遍历:
# 左----中
def dfs(root):
    if not root:
        return
    dfs(root.left)
    dfs(root.right)
	执行操作
	
#二叉树锯齿遍历
class Solution(object):
    def zigzagLevelOrder(self, root):
    #层序遍历
        if not root: 
            return [];
        res, queue = [], collections.deque()
        queue.append(root)
        while queue:
            tmp = []
            for _ in range(len(queue)):
                node = queue.popleft()
                tmp.append(node.val)
                if node.left: queue.append(node.left)
                if node.right: queue.append(node.right)
            res.append(tmp)
        for i in range(len(res)):
            if i%2==0:
                res[i]=res[i];
            else:
                res[i]=res[i][::-1];
        return res

#验证二叉搜索树
class Solution:
    def isValidBST(self, root: TreeNode) -> bool:
        stack, inorder = [], float('-inf')   
        while stack or root:
            while root:
                stack.append(root)
                root = root.left
            root = stack.pop()
            # 如果中序遍历得到的节点的值小于等于前一个 inorder,说明不是二叉搜索树
            if root.val <= inorder:
                return False
            inorder = root.val
            root = root.right

        return True

#平衡二叉树
#计算树的高度并比较
class Solution:
    def isBalanced(self, root:TreeNode)->bool:
        if not root:
            return True;
        leftTreeHeight= self.treeHeight(root.left);
        rightTreeHeight= self.treeHeight(root.right);
                 #平衡二叉树 高度差判断
        if abs(leftTreeHeight-rightTreeHeight)>1:
            return False;
        else:
            return self.isBalanced(root.left) and self.isBalanced(root.right);
    #递归树高度求解    
    def treeHeight(self, root):
        if not root:
            return 0
        return max(self.treeHeight(root.left), self.treeHeight(root.right))+1

三、链表

代码如下(示例):


    

#链表

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

#反转链表
#递归
class Solution:
    def reverseList(self, head: ListNode) -> ListNode:
        #递归结束条件
        if not head or not head.next:
            return head;
        #调用递归函数
        cur=self.reverseList(head.next);
        head.next.next=head;
        head.next=None;
        return cur;
    
#数组的朴素解法
class Solution(object):
    def reverseList(self, head):
        if not head:
            return None;
        res=[];
        #链表 --list
        while head:
            res.append(head.val);
            head=head.next;
        #print(res);
        cur=res[::-1];
        #print(cur);
        dummy=ListNode(cur[0]);
        pur=dummy;
        for i in range(1,len(cur)):
            dummy.next=ListNode(cur[i]);
            dummy=dummy.next;
        return pur;

#固定范围的翻转链表

# 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 reverseBetween(self, head, left, right):
        count = 1
        dummy = ListNode(0)
        dummy.next = head
        pre = dummy
        while pre.next and count < left:
            pre = pre.next
            count += 1
        cur = pre.next
        tail = cur
        #绘图
        while cur and count <= right:
            nxt = cur.next
            cur.next = pre.next
            pre.next = cur
            tail.next = nxt
            cur = nxt
            count += 1
        return dummy.next

class Solution:
    def reverseBetween(self, head: ListNode, left: int, right: int) -> ListNode:
        def reverse_linked_list(head: ListNode):
            # 也可以使用递归反转一个链表
            #pre--cur
            pre = None
            cur = head
            while cur:
                next = cur.next
                cur.next = pre
                pre = cur
                cur = next

        # 因为头节点有可能发生变化,使用虚拟头节点可以避免复杂的分类讨论
        dummy_node = ListNode(-1)
        dummy_node.next = head
        pre = dummy_node
        # 第 1 步:从虚拟头节点走 left - 1 步,来到 left 节点的前一个节点
        # 建议写在 for 循环里,语义清晰
        for _ in range(left - 1):
            pre = pre.next

        # 第 2 步:从 pre 再走 right - left + 1 步,来到 right 节点
        right_node = pre
        for _ in range(right - left + 1):
            right_node = right_node.next
        # 第 3 步:切断出一个子链表(截取链表)
        left_node = pre.next
        curr = right_node.next

        # 注意:切断链接
        pre.next = None
        right_node.next = None

        # 第 4 步:同第 206 题,反转链表的子区间
        reverse_linked_list(left_node)
        # 第 5 步:接回到原来的链表中
        pre.next = right_node
        left_node.next = curr
        return dummy_node.next

    
#头插法
class Solution:
    def reverseBetween(self, head: ListNode, left: int, right: int) -> ListNode:
        # 设置 dummyNode 是这一类问题的一般做法
        dummy_node = ListNode(-1)
        dummy_node.next = head
        pre = dummy_node
        for _ in range(left - 1):
            pre = pre.next

        cur = pre.next
        for _ in range(right - left):
            next = cur.next
            cur.next = next.next
            next.next = pre.next
            pre.next = next
        return dummy_node.next

#旋转链表
class Solution(object):
    def rotateRight(self, head, k):
        if not head:
            return None;
        res=[];
        #链表--list
        while head:
            res.append(head.val);
            head=head.next;
        cur=[0]*len(res);
        for i in range(len(res)):
            #矩阵移位,移位k个位置
            cur[(i+k)%len(res)]=res[i];
        dummy=  ListNode(0);
        pur  =dummy;
        #list--链表
        for i in range(len(cur)):
            dummy.next=ListNode(cur[i]);
            dummy=dummy.next;
        return pur.next;
   

#旋转链表
class Solution:
    def rotateRight(self, head, k):
        if not head or not head.next: return head
        # 求链表长度
        _len = 0
        cur = head
        while cur:
            _len += 1
            cur = cur.next
        # 对长度取模
        k %= _len
        if k == 0: return head
        # 让 fast 先向后走 k 步
        fast, slow = head, head
        while k:
            fast = fast.next
            k -= 1
        # 此时 slow 和 fast 之间的距离是 k;fast 指向第 k+1 个节点
        # 当 fast.next 为空时,fast 指向链表最后一个节点,slow 指向倒数第 k + 1 个节点
        while fast.next:
            fast = fast.next
            slow = slow.next
        # newHead 是倒数第 k 个节点,即新链表的头
        newHead = slow.next
        # 让倒数第 k + 1 个节点 和 倒数第 k 个节点断开
        slow.next = None
        # 让最后一个节点指向原始链表的头
        fast.next = head
        return newHead

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值