diff --git a/problems/0110.平衡二叉树.md b/problems/0110.平衡二叉树.md index abc6833f..640a18a7 100644 --- a/problems/0110.平衡二叉树.md +++ b/problems/0110.平衡二叉树.md @@ -635,6 +635,108 @@ var isBalanced = function(root) { }; ``` +## C +递归法: +```c +int getDepth(struct TreeNode* node) { + //如果结点不存在,返回0 + if(!node) + return 0; + //求出右子树深度 + int rightDepth = getDepth(node->right); + //求出左子树深度 + int leftDepth = getDepth(node->left); + //返回左右子树中的较大值+1 + return rightDepth > leftDepth ? rightDepth + 1 : leftDepth + 1; +} + +bool isBalanced(struct TreeNode* root) { + //递归结束条件为:传入结点为NULL,返回True + if(!root) + return 1; + //求出左右子树的深度 + int leftDepth = getDepth(root->left); + int rightDepth = getDepth(root->right); + int diff; + //若左右子树绝对值差距大于1,返回False + if((diff = leftDepth - rightDepth) > 1 || diff < -1) + return 0; + //检查左右子树是否为平衡二叉树 + return isBalanced(root->right) && isBalanced(root->left); +} +``` + +迭代法: +```c +//计算结点深度 +int getDepth(struct TreeNode* node) { + //开辟栈空间 + struct TreeNode** stack = (struct TreeNode**)malloc(sizeof(struct TreeNode*) * 10000); + int stackTop = 0; + //若传入结点存在,将其入栈。若不存在,函数直接返回0 + if(node) + stack[stackTop++] = node; + int result = 0; + int depth = 0; + + //当栈中有元素时,进行迭代遍历 + while(stackTop) { + //取出栈顶元素 + struct TreeNode* tempNode = stack[--stackTop]; + //若栈顶元素非NULL,则将深度+1 + if(tempNode) { + depth++; + //将栈顶元素再次入栈,添加NULL表示此结点已被遍历 + stack[stackTop++] = tempNode; + stack[stackTop++] = NULL; + //若栈顶元素有左右孩子,则将孩子结点入栈 + if(tempNode->left) + stack[stackTop++] = tempNode->left; + if(tempNode->right) + stack[stackTop++] = tempNode->right; + //更新结果 + result = result > depth ? result : depth; + } + else { + //若为NULL,则代表当前结点已被遍历,深度-1 + tempNode = stack[--stackTop]; + depth--; + } + } + + return result; +} + +bool isBalanced(struct TreeNode* root){ + //开辟栈空间 + struct TreeNode** stack = (struct TreeNode**)malloc(sizeof(struct TreeNode*) * 10000); + int stackTop = 0; + + //若根节点不存在,返回True + if(!root) + return 1; + + //将根节点入栈 + stack[stackTop++] = root; + //当栈中有元素时,进行遍历 + while(stackTop) { + //将栈顶元素出栈 + struct TreeNode* node = stack[--stackTop]; + //计算左右子树的深度 + int diff = getDepth(node->right) - getDepth(node->left); + //若深度的绝对值大于1,返回False + if(diff > 1 || diff < -1) + return 0; + //如果栈顶结点有左右结点,将左右结点入栈 + if(node->left) + stack[stackTop++] = node->left; + if(node->right) + stack[stackTop++] = node->right; + } + //若二叉树遍历结束后没有返回False,则返回True + return 1; +} +``` ----------------------- * 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) diff --git a/problems/1002.查找常用字符.md b/problems/1002.查找常用字符.md index 44a02ceb..5a8d1093 100644 --- a/problems/1002.查找常用字符.md +++ b/problems/1002.查找常用字符.md @@ -331,6 +331,59 @@ func commonChars(_ words: [String]) -> [String] { } ``` +C: +```c +//若两个哈希表定义为char数组(每个单词的最大长度不会超过100,因此可以用char表示),可以提高时间和空间效率 +void updateHashTable(int* hashTableOne, int* hashTableTwo) { + int i; + for(i = 0; i < 26; i++) { + hashTableOne[i] = hashTableOne[i] < hashTableTwo[i] ? hashTableOne[i] : hashTableTwo[i]; + } +} + +char ** commonChars(char ** words, int wordsSize, int* returnSize){ + //用来统计所有字母出现的最小频率 + int hashTable[26] = { 0 }; + //初始化返回的char**数组以及返回数组长度 + *returnSize = 0; + char** ret = (char**)malloc(sizeof(char*) * 100); + + //如果输入数组长度为0,则返回NULL + if(!wordsSize) + return NULL; + + int i; + //更新第一个单词的字母频率 + for(i = 0; i < strlen(words[0]); i++) + hashTable[words[0][i] - 'a']++; + //更新从第二个单词开始的字母频率 + for(i = 1; i < wordsSize; i++) { + //创建新的哈希表,记录新的单词的字母频率 + int newHashTable[26] = { 0 }; + int j; + for(j = 0; j < strlen(words[i]); j++) { + newHashTable[words[i][j] - 'a']++; + } + //更新原哈希表 + updateHashTable(hashTable, newHashTable); + } + + //将哈希表中的字符变为字符串放入ret中 + for(i = 0; i < 26; i++) { + if(hashTable[i]) { + int j; + for(j = 0; j < hashTable[i]; j++) { + char* tempString = (char*)malloc(sizeof(char) * 2); + tempString[0] = i + 'a'; + tempString[1] = '\0'; + ret[(*returnSize)++] = tempString; + } + } + } + return ret; +} +``` + ----------------------- * 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) * B站视频:[代码随想录](https://space.bilibili.com/525438321)