Leetcode题解 - 树、DFS部分简单题目代码+思路(700、671、653、965、547、473、46)

700. 二叉搜索树中的搜索 - 树

给定二叉搜索树(BST)的根节点和一个值。 你需要在BST中找到节点值等于给定值的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 NULL。

思路:
二叉搜索树的特点为左比根小,右比根大。那么目标结点就有三种可能:
1. 和根一样大,那么直接返回根即可。
2. 比根的值小,那么应该再去次左子树中搜索。
3. 比根的值大,那么应该再次去右子树中搜索。
可以看到这就是一个递归的思路。

class Solution:
    def searchBST(self, root: TreeNode, val: int) -> TreeNode:
        if not root:
            return
        if val == root.val:
            return root
        # 比根的值小就去左子树
        if val < root.val:
            lres = self.searchBST(root.left, val)
            if lres: return lres
        # 否则就去右子树
        if val > root.val:
            rres = self.searchBST(root.right, val)
            if rres: return rres
        return None

671. 二叉树中第二小的节点 - 树

给定一个非空特殊的二叉树,每个节点都是正数,并且每个节点的子节点数量只能为 2 或 0。如果一个节点有两个子节点的话,那么这个节点的值不大于它的子节点的值。

给出这样的一个二叉树,你需要输出所有节点中的第二小的值。如果第二小的值不存在的话,输出 -1 。

思路:
(并没有想到很巧妙的方法emmm)
直接BFS遍历树,将大于根结点的值都保存起来(因为题目条件中说明了子节点的值都是大于or等于父节点的,那么根一定是最小的),如果这些值存在那么最小的一个一定为第二小的,否则就是不存在。

#         self.right = None
class Solution:
    def findSecondMinimumValue(self, root: TreeNode) -> int:
        if not root:
            return -1
        Q = [root]
        res = []
        while len(Q) != 0:
            node = Q.pop(0)
            if node.val > root.val:
                res.append(node.val)
            if node.left:
                Q.append(node.left)
            if node.right:
                Q.append(node.right)
        if len(res) == 0:
            return -1
        return min(res)

653. 两数之和 IV - 输入 BST - 树 -> 双指针

给定一个二叉搜索树和一个目标结果,如果 BST 中存在两个元素且它们的和等于给定的目标结果,则返回 true。

思路:
(看了题解才想出来...两个数字和的问题似乎经常和双指针有关)
因为是二叉搜索树,所以中序遍历的结果就是一个递增序列。双指针法的前提就是递增序列,然后用一个指针指向头,一个指针指向尾,不断移动两个指针判断是否符合条件。

 class Solution:
    def findTarget(self, root: TreeNode, k: int) -> bool:
        inRes = []
        # 中序遍历
        def Inorder(root):
            if not root:
                return
            Inorder(root.left)
            inRes.append(root.val)
            Inorder(root.right)
        Inorder(root)
        # 双指针
        head = 0; tail = len(inRes) - 1
        while head < tail:
            res = inRes[head] + inRes[tail]
            # 如果大于目标值,就让尾指针左移
            if res > k:
                tail -= 1
            # 如果小于目标值,就让头指针右移
            if res < k:
                head += 1
            if res == k:
                return True
        return False

965. 单值二叉树 - 树

如果二叉树每个节点都具有相同的值,那么该二叉树就是单值二叉树。

只有给定的树是单值二叉树时,才返回 true;否则返回 false。

思路:
遍历一遍树即可,这里采用的是层次遍历,但凡出现和根结点的值不同的值就绝对不是单值。

class Solution:
    def isUnivalTree(self, root: TreeNode) -> bool:
        if not root:
            return False
        Q = [root]
        check = root.val
        while len(Q) != 0:
            node = Q.pop(0)
            if node.val != check:
                return False
            if node.left:
                Q.append(node.left)
            if node.right:
                Q.append(node.right)
        return True

547. 朋友圈 - DFS -> 统计连通块的数量

班上有 N 名学生。其中有些人是朋友,有些则不是。他们的友谊具有是传递性。如果已知 A 是 B 的朋友,B 是 C 的朋友,那么我们可以认为 A 也是 C 的朋友。所谓的朋友圈,是指所有朋友的集合。

给定一个 N * N 的矩阵 M,表示班级中学生之间的朋友关系。如果M[i][j] = 1,表示已知第 i 个和 j 个学生互为朋友关系,否则为不知道。你必须输出所有学生中的已知的朋友圈总数。

思路:
直接套DFS模板即可,相当于判断一共做了几次DFS。
这个题的本质就是在求图中有几个连通块。

class Solution:
    def findCircleNum(self, M: List[List[int]]) -> int:
        res = 0
        vis = set()
        # 每一次的DFS都会把属于同一个朋友圈的人加上vis中
        def DFS(node):
            vis.add(node)
            for i in range(len(M[node])):
                if M[node][i] == 1 and i not in vis:
                    DFS(i)
        for i in range(len(M)):
            # 剩下的没有被加入vis中才会再次进行DFS
            if i not in vis:
                DFS(i)
                res += 1
        return res

DFS - 求出所有的组合

473. 火柴拼正方形 - 含重复

输入为小女孩拥有火柴的数目,每根火柴用其长度表示。输出即为是否能用所有的火柴拼成正方形。

输入: [1,1,2,2,2]
输出: true
解释: 能拼成一个边长为2的正方形,每边两根火柴。

输入: [3,3,3,3,4]
输出: false
解释: 不能用所有火柴拼成一个正方形。

思路:
对于每一根火柴来说,它都有四个边可以去(不同的火柴可以去相同的边),这样只要求解出所有火柴的每一种摆放组合就可以得知是否能够称为正方形

"""
DFS遍历所有可能性
本题剪枝很重要,不然会很容易超时。
"""
class Solution:
    def makesquare(self, nums) -> bool:
        # 如果数组和不是4的倍数,一定不能拼成正方形
        sumRes = sum(nums)
        if len(nums) < 4 or sum(nums) % 4 != 0:
            return False
        # 若有一个数大于数组和/4,也一定不能拼成正方形
        check = sumRes // 4
        nums.sort(reverse=True)
        if nums[0] > check:
            return False
        # 遍历每根火柴loc为该跟火柴的下标,square为正方形的各个边
        def DFS(loc, square):
            if len(set(square)) == 1 and 0 not in square and loc == len(nums):
                return True
            if loc > len(nums) -1:
                return
            # 每根火柴有四个地方可以放置
            for i in range(4):
                if square[i] + nums[loc] <= check:
                    square[i] += nums[loc]
                    # 让下一个位置的火柴去放
                    if DFS(loc + 1, square):
                        return True
                    # 表示不应该放在这个位置
                    square[i] -= nums[loc]
            return False
        return DFS(0, [0, 0, 0, 0])
46. 全排列 - 不含重复

给定一个没有重复数字的序列,返回其所有可能的全排列。

思路:
就是DFS的套路,(一共有n个数字,n个位置)每个位置都有n个数字可以选择,在一次排列中一个数字只能属于一个位置。

 class Solution:
    def permute(self, nums):
        vis = set()
        r = []
        def DFS(loc, res):
            if loc == len(nums):
                r.append(res.copy())
            # 每个位置n个数字
            for i in nums:
                if i not in vis:
                    vis.add(i)
                    res[loc] = i
                    DFS(loc + 1, res)
                    vis.remove(i)
        DFS(0, [0] * len(nums))
        return sorted(r)

原文地址:https://www.cnblogs.com/NFii/p/11979393.html

时间: 2024-10-28 21:46:06

Leetcode题解 - 树、DFS部分简单题目代码+思路(700、671、653、965、547、473、46)的相关文章

Leetcode题解 - 贪心算法部分简单题目代码+思路(860、944、1005、1029、1046、1217、1221)

leetcode真的是一个学习阅读理解的好地方 860. 柠檬水找零 """ 因为用户支付的只会有5.10.20 对于10元的用户必须找一个5 对于20元的用户可以找(三个5)或者(一个10一个5),每次都从大的开始找起来 """ class Solution: def lemonadeChange(self, bills) -> bool: five = 0 ten = 0 for i in bills: if i == 5: five

Leetcode题解 - DFS部分题目代码+思路(756、1034、1110、491、721、988)

756. 金字塔转换矩阵 """ 学到的新知识: from collections import defaultditc可以帮我们初始化字典,不至于取到某个不存在的值的时候报错.例如列表类型就会默认初始值为[],str对应的是空字符串,set对应set( ),int对应0 思路: 通过本层构建上一层(DFS,类似于全排列),看是否能构建成功(递归) """ from collections import defaultdict class Sol

Leetcode题解 - 链表简单部分题目代码+思路(21、83、203、206、24、19、876)

??本次部分没有带题目,因为链表系列的题目有的非常直观,从名字中就能知道到底需要做什么. 21. 合并两个有序链表 """ (用中间链表的方法)可以想象为双指针,分别指向两个链表,比较指针当前指向的值(因为是比较当前的值所以不需要判断next是否为空),拥有较小值的链表指针后移. """ class Solution: def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNo

Leetcode 与树(TreeNode )相关的题解测试工具函数总结

LeetCode收录了许多互联网公司的算法题目,被称为刷题神器.最近在剑指Offer上也刷了一些题目,发现涉及到数据结构类的题目,比如说"树"."链表"这种题目,如果想在本地IDE进行测试,除了完成题目要求的算法外,还需要写一些辅助函数,比如树的创建,遍历等,由于这些函数平时用到的地方比较多,并且也能加深对常用数据结构的理解,这里将Leetcode中与树(TreeNode)相关题目会用到的测试辅助函数做一个总结. 代码文件说明 LeetCode 剑指Offer在线编

leetcode题解:Binary Tree Postorder Traversal (二叉树的后序遍历)

题目: Given a binary tree, return the postorder traversal of its nodes' values. For example:Given binary tree {1,#,2,3}, 1 2 / 3 return [3,2,1]. Note: Recursive solution is trivial, could you do it iteratively? 说明: 1) 两种实现,递归与非递归 , 其中非递归有两种方法 2)复杂度分析:时

LeetCode总结 -- 树的构造篇

这篇总结主要介绍树中比较常见的一类题型--树的构造.其实本质还是用递归的手法来实现,但是这类题目有一个特点,就是它是构建一棵树,而不是给定一棵树,然后进行遍历,所以实现起来思路上有点逆向,还是要练习一下.LeetCode中关于树的构造的题目有以下几道:Convert Sorted Array to Binary Search TreeConvert Sorted List to Binary Search TreeConstruct Binary Tree from Preorder and I

Clone Graph leetcode java(DFS and BFS 基础)

题目: Clone an undirected graph. Each node in the graph contains a label and a list of its neighbors. OJ's undirected graph serialization: Nodes are labeled uniquely. We use # as a separator for each node, and , as a separator for node label and each n

【LeetCode】树(共94题)

[94]Binary Tree Inorder Traversal [95]Unique Binary Search Trees II (2018年11月14日,算法群) 给了一个 n,返回结点是 1 - n 的所有形态的BST. 题解:枚举每个根节点 r, 然后递归的生成左右子树的所有集合,然后做笛卡尔积. 1 /** 2 * Definition for a binary tree node. 3 * struct TreeNode { 4 * int val; 5 * TreeNode *

[LeetCode]题解(python):096-Unique Binary Search Trees

题目来源: https://leetcode.com/problems/unique-binary-search-trees/ 题意分析: 给定一个整数n,返回所有中序遍历是1到n的树的可能. 题目思路: 这是动态规划的题目.选定了第k个为根节点,那么所有的可能就是ans[k-1] * ans[n -k]其中,ans[i]代表i整数i一共有ans[i]种可能. 代码(python): class Solution(object): def numTrees(self, n): ""&q