2022-6-18 排序的循环链表,验证二叉树,二叉树中的列表,二叉树中的伪回文路径,二叉搜索子树的最大键值和

1. 排序的循环链表

给定循环单调非递减列表中的一个点,写一个函数向这个列表中插入一个新元素 insertVal ,使这个列表仍然是循环升序的。

给定的可以是这个列表中任意一个顶点的指针,并不一定是这个列表中最小元素的指针。

如果有多个满足条件的插入位置,可以选择任意一个位置插入新的值,插入后整个列表仍然保持有序。

如果列表为空(给定的节点是 null),需要创建一个循环有序列表并返回这个节点。否则。请返回原先给定的节点。

Example 1

输入:head = [3,4,1], insertVal = 2
输出:[3,4,1,2]

Example 2

输入:head = [], insertVal = 1
输出:[1]

Constraints:

  • 0 <= Number of Nodes <= 5 * 10^4
  • -10^6 <= Node.val <= 10^6
  • -10^6 <= insertVal <= 10^6

代码 [链表]

class Solution {
public:
    Node *insert(Node *head, int insertVal) {
        if (head == nullptr) {
            head = new Node(insertVal);
            head->next = head;
            return head;
        }
        auto cur = head;
        // 可分为两种情况, 1.链表 
        
        
        中存在不同元素, 2.链表中所有元素相等
        while (cur->next != head) { // 若从这个出口退出, 则链表中所有元素相等
            if (cur->next->val < cur->val) { // 考虑边界情况
                if (insertVal <= cur->next->val || cur->val <= insertVal) break;
            }
            if (cur->val <= insertVal && insertVal <= cur->next->val) break; // 正常情况
            cur = cur->next;
        }
        cur->next = new Node(insertVal, cur->next);
        return head;
    }
};

2. 验证二叉树

You have n binary tree nodes numbered from 0 to n - 1 where node i has two children leftChild[i] and rightChild[i], return true if and only if all the given nodes form exactly one valid binary tree.

If node i has no left child then leftChild[i] will equal -1, similarly for the right child.

Note that the nodes have no values and that we only use the node numbers in this problem.

Example 1

Input: n = 4, leftChild = [1,-1,3,-1], rightChild = [2,-1,-1,-1]
Output: true

Example 2

Input: n = 4, leftChild = [1,-1,3,-1], rightChild = [2,3,-1,-1]
Output: false

Constraints:

  • n == leftChild.length == rightChild.length
  • 1 <= n <= 10^4
  • -1 <= leftChild[i], rightChild[i] <= n - 1

代码 [DFS]

class Solution {
private:
    bool visited[10001];

    bool dfs(int node, const vector<int> &leftChild, const vector<int> &rightChild) {
        if (visited[node]) return false;
        visited[node] = true;
        if (leftChild[node] != -1 && !dfs(leftChild[node], leftChild, rightChild)) return false;
        if (rightChild[node] != -1 && !dfs(rightChild[node], leftChild, rightChild)) return false;
        return true;
    }

public:
    bool validateBinaryTreeNodes(int n, const vector<int> &leftChild, const vector<int> &rightChild) {
        vector<int> indeg(n, 0);
        for (auto node:leftChild)
            if (node != -1) { if (++indeg[node] == 2) return false; } // 二叉树节点入度只能是0/1
        for (auto node:rightChild)
            if (node != -1) { if (++indeg[node] == 2) return false; } // 二叉树节点入度只能是0/1
        int root = -1;
        for (int i = 0; i < n; ++i) // 查找根节点
            if (indeg[i] == 0) {
                if (root == -1) {
                    root = i;
                } else {
                    return false; // 存在两个根节点,即图不连通
                }
            }
        if (root == -1) return false; // 连通图
        if (!dfs(root, leftChild, rightChild)) return false; // 遍历节点判断是否存在环
        return all_of(visited, visited + n, [](const bool flag) { return flag; }); // 再次判断是否图不连通(存在一个二叉树+一个连通图的情况)
    }
};

3. 二叉树中的列表

Given a binary tree root and a linked list with head as the first node.

Return True if all the elements in the linked list starting from the head correspond to some downward path connected in the binary tree otherwise return False.

In this context downward path means a path that starts at some node and goes downwards.

Example 1

Input: head = [4,2,8], root = [1,4,4,null,2,2,null,1,null,6,8,null,null,null,null,1,3]
Output: true
Explanation: Nodes in blue form a subpath in the binary Tree.  

Example 2

Input: head = [1,4,2,6], root = [1,4,4,null,2,2,null,1,null,6,8,null,null,null,null,1,3]
Output: true

Constraints:

  • The number of nodes in the tree will be in the range [1, 2500].
  • The number of nodes in the list will be in the range [1, 100].
  • 1 <= Node.val <= 100 for each node in the linked list and binary tree.

代码 [DFS]

class Solution {
private:
    bool check(ListNode *head, TreeNode *root) {
        if (head == nullptr) return true;
        if (root == nullptr || head->val != root->val) return false;
        return check(head->next, root->left) || check(head->next, root->right);
    }

public:
    bool isSubPath(ListNode *head, TreeNode *root) {
        if (root == nullptr) return false;
        if (check(head, root)) return true;
        return isSubPath(head, root->left) || isSubPath(head, root->right);
    }
};

4. 二叉树中的伪回文路径

给你一棵二叉树,每个节点的值为 1 到 9 。我们称二叉树中的一条路径是 「伪回文」的当它满足:路径经过的所有节点值的排列中,存在一个回文序列。

请你返回从根到叶子节点的所有路径中 伪回文 路径的数目。

Example 1

输入:root = [2,3,1,3,1,null,1]
输出:2 

Example 2

输入:root = [2,1,1,1,3,null,null,null,null,null,1]
输出:1 

Constraints:

  • 给定二叉树的节点数目在范围 [1, 10^5]
  • 1 <= Node.val <= 9

代码 [DFS]

class Solution {
private:
    void dfs(TreeNode *node, int flag, int &result) {
        flag ^= (1 << node->val);
        if (!node->left && !node->right) result += __builtin_popcount(flag) == 1 || flag==0;
        if (node->left) dfs(node->left, flag, result);
        if (node->right) dfs(node->right, flag, result);
    }

public:
    int pseudoPalindromicPaths(TreeNode *root) {
        int result = 0;
        dfs(root, 0, result);
        return result;
    }
};

4. 二叉搜索子树的最大键值和

Given a binary tree root, return the maximum sum of all keys of any sub-tree which is also a Binary Search Tree (BST).

Assume a BST is defined as follows:

  • The left subtree of a node contains only nodes with keys less than the node’s key.
  • The right subtree of a node contains only nodes with keys greater than the node’s key.
  • Both the left and right subtrees must also be binary search trees.

Example 1

Input: root = [1,4,3,2,4,2,5,null,null,null,null,null,null,4,6]
Output: 20
Explanation: Maximum sum in a valid Binary search tree is obtained in root node with key equal to 3.

Example 2

Input: root = [4,3,null,1,2]
Output: 2
Explanation: Maximum sum in a valid Binary search tree is obtained in a single root node with key equal to 2.

Constraints:

  • The number of nodes in the tree is in the range [1, 4 * 10^4].
  • -4 * 10^4 <= Node.val <= 4 * 10^4

代码 [DFS]

class Solution {
private:
    using tp = tuple<int, int, int, bool>; // lo, hi, sum, flag
    int ans = 0;

    tp dfs(TreeNode *root) {
        if (!root->left && !root->right) { // 退出条件: 叶子节点
            ans = max(ans, root->val);
            return {root->val, root->val, root->val, true};
        }
        int lo_ = root->val, hi_ = root->val, sum_ = root->val;
        bool flag_ = true;
        if (root->left) {
            auto[lo, hi, sum, flag]=dfs(root->left);
            if (!flag || hi >= root->val) flag_ = false;
            lo_ = lo, sum_ += sum;
        }
        if (root->right) {
            auto[lo, hi, sum, flag]=dfs(root->right);
            if (!flag || lo <= root->val) flag_ = false;
            hi_ = hi, sum_ += sum;
        }
        if (!flag_) return {0, 0, 0, false};
        ans = max(ans, sum_);
        return {lo_, hi_, sum_, true};
    }


public:
    int maxSumBST(TreeNode *root) {
        dfs(root);
        return ans;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值