mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-07-12 21:50:49 +08:00
Merge pull request #862 from KingArthur0205/remote
添加 0106.从中序与后续遍历构造二叉树.md,0206.翻转链表.md, 0344.反转字符串 以及0226.翻转二叉树.md C语言版本
This commit is contained in:
@ -819,6 +819,81 @@ var buildTree = function(preorder, inorder) {
|
||||
};
|
||||
```
|
||||
|
||||
## C
|
||||
106 从中序与后序遍历序列构造二叉树
|
||||
```c
|
||||
int linearSearch(int* arr, int arrSize, int key) {
|
||||
int i;
|
||||
for(i = 0; i < arrSize; i++) {
|
||||
if(arr[i] == key)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct TreeNode* buildTree(int* inorder, int inorderSize, int* postorder, int postorderSize){
|
||||
//若中序遍历数组中没有元素,则返回NULL
|
||||
if(!inorderSize)
|
||||
return NULL;
|
||||
//创建一个新的结点,将node的val设置为后序遍历的最后一个元素
|
||||
struct TreeNode* node = (struct TreeNode*)malloc(sizeof(struct TreeNode));
|
||||
node->val = postorder[postorderSize - 1];
|
||||
|
||||
//通过线性查找找到中间结点在中序数组中的位置
|
||||
int index = linearSearch(inorder, inorderSize, postorder[postorderSize - 1]);
|
||||
|
||||
//左子树数组大小为index
|
||||
//右子树的数组大小为数组大小减index减1(减的1为中间结点)
|
||||
int rightSize = inorderSize - index - 1;
|
||||
node->left = buildTree(inorder, index, postorder, index);
|
||||
node->right = buildTree(inorder + index + 1, rightSize, postorder + index, rightSize);
|
||||
return node;
|
||||
}
|
||||
```
|
||||
|
||||
105 从前序与中序遍历序列构造二叉树
|
||||
```c
|
||||
struct TreeNode* buildTree(int* preorder, int preorderSize, int* inorder, int inorderSize){
|
||||
// 递归结束条件:传入的数组大小为0
|
||||
if(!preorderSize)
|
||||
return NULL;
|
||||
|
||||
// 1.找到前序遍历数组的第一个元素, 创建结点。左右孩子设置为NULL。
|
||||
int rootValue = preorder[0];
|
||||
struct TreeNode* root = (struct TreeNode*)malloc(sizeof(struct TreeNode));
|
||||
root->val = rootValue;
|
||||
root->left = NULL;
|
||||
root->right = NULL;
|
||||
|
||||
// 2.若前序遍历数组的大小为1,返回该结点
|
||||
if(preorderSize == 1)
|
||||
return root;
|
||||
|
||||
// 3.根据该结点切割中序遍历数组,将中序遍历数组分割成左右两个数组。算出他们的各自大小
|
||||
int index;
|
||||
for(index = 0; index < inorderSize; index++) {
|
||||
if(inorder[index] == rootValue)
|
||||
break;
|
||||
}
|
||||
int leftNum = index;
|
||||
int rightNum = inorderSize - index - 1;
|
||||
|
||||
int* leftInorder = inorder;
|
||||
int* rightInorder = inorder + leftNum + 1;
|
||||
|
||||
// 4.根据中序遍历数组左右数组的各子大小切割前序遍历数组。也分为左右数组
|
||||
int* leftPreorder = preorder+1;
|
||||
int* rightPreorder = preorder + 1 + leftNum;
|
||||
|
||||
// 5.递归进入左右数组,将返回的结果作为根结点的左右孩子
|
||||
root->left = buildTree(leftPreorder, leftNum, leftInorder, leftNum);
|
||||
root->right = buildTree(rightPreorder, rightNum, rightInorder, rightNum);
|
||||
|
||||
// 6.返回根节点
|
||||
return root;
|
||||
}
|
||||
```
|
||||
|
||||
-----------------------
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
||||
|
@ -412,6 +412,45 @@ func reverse(pre: ListNode?, cur: ListNode?) -> ListNode? {
|
||||
}
|
||||
```
|
||||
|
||||
C:
|
||||
双指针法:
|
||||
```c
|
||||
struct ListNode* reverseList(struct ListNode* head){
|
||||
//保存cur的下一个结点
|
||||
struct ListNode* temp;
|
||||
//pre指针指向前一个当前结点的前一个结点
|
||||
struct ListNode* pre = NULL;
|
||||
//用head代替cur,也可以再定义一个cur结点指向head。
|
||||
while(head) {
|
||||
//保存下一个结点的位置
|
||||
temp = head->next;
|
||||
//翻转操作
|
||||
head->next = pre;
|
||||
//更新结点
|
||||
pre = head;
|
||||
head = temp;
|
||||
}
|
||||
return pre;
|
||||
}
|
||||
```
|
||||
|
||||
递归法:
|
||||
```c
|
||||
struct ListNode* reverse(struct ListNode* pre, struct ListNode* cur) {
|
||||
if(!cur)
|
||||
return pre;
|
||||
struct ListNode* temp = cur->next;
|
||||
cur->next = pre;
|
||||
//将cur作为pre传入下一层
|
||||
//将temp作为cur传入下一层,改变其指针指向当前cur
|
||||
return reverse(cur, temp);
|
||||
}
|
||||
|
||||
struct ListNode* reverseList(struct ListNode* head){
|
||||
return reverse(NULL, head);
|
||||
}
|
||||
```
|
||||
|
||||
-----------------------
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
||||
|
@ -565,6 +565,51 @@ var invertTree = function(root) {
|
||||
};
|
||||
```
|
||||
|
||||
C:
|
||||
递归法
|
||||
```c
|
||||
struct TreeNode* invertTree(struct TreeNode* root){
|
||||
if(!root)
|
||||
return NULL;
|
||||
//交换结点的左右孩子(中)
|
||||
struct TreeNode* temp = root->right;
|
||||
root->right = root->left;
|
||||
root->left = temp;
|
||||
左
|
||||
invertTree(root->left);
|
||||
//右
|
||||
invertTree(root->right);
|
||||
return root;
|
||||
}
|
||||
```
|
||||
迭代法:深度优先遍历
|
||||
```c
|
||||
struct TreeNode* invertTree(struct TreeNode* root){
|
||||
if(!root)
|
||||
return NULL;
|
||||
//存储结点的栈
|
||||
struct TreeNode** stack = (struct TreeNode**)malloc(sizeof(struct TreeNode*) * 100);
|
||||
int stackTop = 0;
|
||||
//将根节点入栈
|
||||
stack[stackTop++] = root;
|
||||
//若栈中还有元素(进行循环)
|
||||
while(stackTop) {
|
||||
//取出栈顶元素
|
||||
struct TreeNode* temp = stack[--stackTop];
|
||||
//交换结点的左右孩子
|
||||
struct TreeNode* tempNode = temp->right;
|
||||
temp->right = temp->left;
|
||||
temp->left = tempNode;
|
||||
//若当前结点有左右孩子,将其入栈
|
||||
if(temp->right)
|
||||
stack[stackTop++] = temp->right;
|
||||
if(temp->left)
|
||||
stack[stackTop++] = temp->left;
|
||||
}
|
||||
return root;
|
||||
}
|
||||
```
|
||||
|
||||
-----------------------
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
||||
|
@ -218,12 +218,19 @@ func reverseString(_ s: inout [Character]) {
|
||||
}
|
||||
}
|
||||
|
||||
// 双指针法 - 库函数
|
||||
func reverseString(_ s: inout [Character]) {
|
||||
var j = s.count - 1
|
||||
for i in 0 ..< Int(Double(s.count) * 0.5) {
|
||||
s.swapAt(i, j)
|
||||
j -= 1
|
||||
```
|
||||
|
||||
C:
|
||||
```c
|
||||
void reverseString(char* s, int sSize){
|
||||
int left = 0;
|
||||
int right = sSize - 1;
|
||||
|
||||
while(left < right) {
|
||||
char temp = s[left];
|
||||
s[left++] = s[right];
|
||||
s[right--] = temp;
|
||||
|
||||
}
|
||||
}
|
||||
```
|
||||
|
Reference in New Issue
Block a user