力扣 二叉搜索树中的众树

力扣 二叉搜索树中的众树

haimian
2024-11-30 / 0 评论 / 5 阅读 / 正在检测是否收录...
温馨提示:
本文最后更新于2024年11月30日,已超过140天没有更新,若内容或图片失效,请留言反馈。

给你一个含重复值的二叉搜索树(BST)的根节点 root ,找出并返回 BST 中的所有 众数(即,出现频率最高的元素)。

如果树中有不止一个众数,可以按 任意顺序 返回。

假定 BST 满足如下定义:

结点左子树中所含节点的值 小于等于 当前节点的值
结点右子树中所含节点的值 大于等于 当前节点的值
左子树和右子树都是二叉搜索树

上代码



// 比较函数,用于qsort
int compare(const void * a, const void * b) {
    struct ValueCount *va = (struct ValueCount *)a;
    struct ValueCount *vb = (struct ValueCount *)b;

    return vb->count - va->count;
}

// 中序遍历二叉树,统计每个节点值的出现次数
void inorderTraversal(struct TreeNode *node, struct ValueCount **valueCounts, int *countIndex, int *maxSize) {
    if (node == NULL) {
        return;
    }

    inorderTraversal(node->left, valueCounts, countIndex, maxSize);

    int i;
    for (i = 0; i < *countIndex; i++) {
        if ((*valueCounts)[i].value == node->val) {
            (*valueCounts)[i].count++;
            break;
        }
    }
    if (i == *countIndex) {
        // 检查是否需要扩容数组
        if (*countIndex >= *maxSize) {
            // 扩容策略,这里简单地翻倍
            *maxSize *= 2;
            struct ValueCount *newArray = (struct ValueCount *)realloc(*valueCounts, sizeof(struct ValueCount) * (*maxSize));
            if (newArray == NULL) {
                // 处理内存分配失败的情况
                printf("内存分配失败!\n");
                exit(1);
            }
            *valueCounts = newArray;
        }
        (*valueCounts)[*countIndex].value = node->val;
        (*valueCounts)[*countIndex].count = 1;
        (*countIndex)++;
    }

    inorderTraversal(node->right, valueCounts, countIndex, maxSize);
}

// 找出众数并返回结果数组
int *findMode(struct TreeNode *root, int *returnSize) {
    // 初始分配足够的空间,这里假设初始大小为10
    int maxSize = 10;
    // 用于存储节点值及其出现次数的数组
    struct ValueCount *valueCounts = (struct ValueCount *)malloc(sizeof(struct ValueCount) * maxSize);
    int countIndex = 0;

    // 中序遍历二叉树,统计节点值出现次数
    inorderTraversal(root, &valueCounts, &countIndex, &maxSize);

    // 根据出现次数对valueCounts数组进行排序
    qsort(valueCounts, countIndex, sizeof(struct ValueCount), compare);

    // 找出最大出现次数
    int maxCount = valueCounts[0].count;

    // 统计众数的个数
    int modeCount = 0;
    for (int i = 0; i < countIndex; i++) {
        if (valueCounts[i].count == maxCount) {
            modeCount++;
        } else {
            break;
        }
    }

    // 分配返回结果数组的空间
    int *modes = (int *)malloc(sizeof(int) * modeCount);

    // 将众数填充到返回结果数组中
    int j = 0;
    for (int i = 0; i < countIndex && j < modeCount; i++) {
        if (valueCounts[i].count == maxCount) {
            modes[j] = valueCounts[i].value;
            j++;
        }
    }

    // 释放用于统计节点值出现次数的数组空间
    free(valueCounts);

    // 设置返回结果数组的大小
    *returnSize = modeCount;

    return modes;
}

思路很简单,思路就是先把树进行一个中序排序,接下来进行把一个一个数字都放到哈希表里面,然后一个一个循环哈希表里面的数字,进行排序。选出一个最大的来,思路就是这个样子
m44brpnf.png

0

评论 (0)

取消