Skip to content

Commit d8e35a5

Browse files
committed
Merge branch 'master' of github.com:cls1991/leetcode
2 parents 0f584e3 + 25ece25 commit d8e35a5

4 files changed

+440
-0
lines changed

Tree/llb/437. Path Sum III.cpp

+90
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*
2+
问题描述:
3+
You are given a binary tree in which each node contains an integer value.
4+
5+
Find the number of paths that sum to a given value.
6+
7+
The path does not need to start or end at the root or a leaf, but it must go downwards (traveling only from parent nodes to child nodes).
8+
9+
The tree has no more than 1,000 nodes and the values are in the range -1,000,000 to 1,000,000.
10+
11+
Example:
12+
13+
root = [10,5,-3,3,2,null,11,3,-2,null,1], sum = 8
14+
15+
10
16+
/ \
17+
5 -3
18+
/ \ \
19+
3 2 11
20+
/ \ \
21+
3 -2 1
22+
23+
Return 3. The paths that sum to 8 are:
24+
25+
1. 5 -> 3
26+
2. 5 -> 2 -> 1
27+
3. -3 -> 11
28+
*/
29+
30+
/**
31+
* Definition for a binary tree node.
32+
* struct TreeNode {
33+
* int val;
34+
* TreeNode *left;
35+
* TreeNode *right;
36+
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
37+
* };
38+
*/
39+
class Solution {
40+
public:
41+
42+
/*思考:
43+
利用前序遍历的思想,对于每个遍历到的节点进行处理,维护一个变量pre来记录之前路径的和,
44+
然后加上当前节点值,如果加上之后路径之和为sum,那么返回时要加一,然后递归调用左右子树
45+
*/
46+
/*
47+
int pathSum(TreeNode* root, int sum) {
48+
if (!root)
49+
return 0;
50+
return help(root, 0, sum) + pathSum(root->left, sum) + pathSum(root->right, sum);
51+
}
52+
53+
int help (TreeNode* node, int pre, int &sum) {
54+
if (!node)
55+
return 0;
56+
int cur = pre + node->val;
57+
return (cur == sum) + help(node->left, cur, sum) + help(node->right, cur, sum);
58+
}
59+
*/
60+
61+
//思考二:
62+
int pathSum(TreeNode* root, int sum) {
63+
int count = 0;
64+
vector<TreeNode*> vec;
65+
helper(root, sum, 0, vec, count);
66+
return count;
67+
}
68+
69+
void helper(TreeNode* node, int sum, int curSum, vector<TreeNode*> &vec, int &count) {
70+
if (!node)
71+
return;
72+
73+
curSum += node->val;
74+
vec.push_back(node);
75+
//如果加入该节点后,值相等了,就多了条
76+
if (curSum == sum)
77+
count++;
78+
int temp = curSum;
79+
//再判断加上该点后,它与之前的子路径之和
80+
for (int i=0; i<vec.size()-1; ++i) {
81+
temp -= vec[i]->val;
82+
if (temp == sum)
83+
count++;
84+
}
85+
//然后判断左右子树
86+
helper(node->left, sum, curSum, vec, count);
87+
helper(node->right, sum, curSum, vec, count);
88+
vec.pop_back();
89+
}
90+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
/*
2+
问题描述:
3+
Serialization is the process of converting a data structure or object into a sequence of bits so that it can be stored in a file or memory buffer, or transmitted across a network connection link to be reconstructed later in the same or another computer environment.
4+
5+
Design an algorithm to serialize and deserialize a binary search tree. There is no restriction on how your serialization/deserialization algorithm should work. You just need to ensure that a binary search tree can be serialized to a string and this string can be deserialized to the original tree structure.
6+
7+
The encoded string should be as compact as possible.
8+
9+
Note: Do not use class member/global/static variables to store states. Your serialize and deserialize algorithms should be stateless.
10+
*/
11+
12+
//注意这个问题是要求你进行序列化和反序列化二叉查找树
13+
14+
/**
15+
* Definition for a binary tree node.
16+
* struct TreeNode {
17+
* int val;
18+
* TreeNode *left;
19+
* TreeNode *right;
20+
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
21+
* };
22+
*/
23+
class Codec {
24+
public:
25+
26+
27+
//思路一:采用层序遍历的方式进行,借助queue来实现,本质是BFS算法,并且得借助输入、输出流
28+
// Encodes a tree to a single string.
29+
/*
30+
string serialize(TreeNode* root) {
31+
if (!root)
32+
return "";
33+
34+
ostringstream os; //cpp输出流
35+
queue<TreeNode*> q;
36+
q.push(root);
37+
while (!q.empty()) {
38+
TreeNode* node = q.front();
39+
q.pop();
40+
if (node) {
41+
os << node->val << " "; //如果存在改node,输出值和空格,负责输出#
42+
q.push(node->left);
43+
q.push(node->right);
44+
}
45+
else {
46+
os << "#";
47+
}
48+
}
49+
50+
return os.str();
51+
}
52+
53+
// Decodes your encoded data to tree.
54+
TreeNode* deserialize(string data) {
55+
if (data.empty())
56+
return NULL;
57+
58+
istringstream is(data);
59+
queue<TreeNode*> q;
60+
string val = "";
61+
//生成根节点
62+
is >> val;
63+
TreeNode* root = new TreeNode(stoi(val));
64+
TreeNode* cur = root;
65+
q.push(cur);
66+
while (!q.empty()) {
67+
TreeNode* node = q.front();
68+
q.pop();
69+
//一步步从序列里面读取node信息
70+
if (!(is >> val))
71+
break;
72+
if (val != "#") {
73+
cur = new TreeNode(stoi(val));
74+
q.push(cur);
75+
node->left = cur;
76+
}
77+
if (!(is >> val))
78+
break;
79+
if (val != "#") {
80+
cur = new TreeNode(stoi(val));
81+
q.push(cur);
82+
node->right = cur;
83+
}
84+
}
85+
86+
return root;
87+
}
88+
*/
89+
90+
91+
92+
//思路二:利用递归的思想
93+
string serialize(TreeNode* root) {
94+
ostringstream os;
95+
serializeHelper(root, os);
96+
return os.str();
97+
}
98+
99+
void serializeHelper(TreeNode* node, ostringstream &os) {
100+
if (!node) {
101+
os << "# "; //注意写入的是#还有空格
102+
}
103+
else {
104+
os << node->val << " ";
105+
//然后加入左子树和右子树
106+
serializeHelper(node->left, os);
107+
serializeHelper(node->right, os);
108+
}
109+
}
110+
111+
TreeNode* deserialize(string data) {
112+
istringstream is(data);
113+
return deserializeHelper(is);
114+
}
115+
116+
TreeNode* deserializeHelper(istringstream &is) {
117+
string val = "";
118+
is >> val;
119+
if (val == "#")
120+
return NULL;
121+
//其他的需要生成新的node
122+
TreeNode *node = new TreeNode(stoi(val));
123+
node->left = deserializeHelper(is);
124+
node->right = deserializeHelper(is);
125+
return node;
126+
}
127+
128+
};
129+
130+
// Your Codec object will be instantiated and called as such:
131+
// Codec codec;
132+
// codec.deserialize(codec.serialize(root));
+135
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
/*
2+
问题描述:
3+
4+
Given a root node reference of a BST and a key, delete the node with the given key in the BST. Return the root node reference (possibly updated) of the BST.
5+
6+
Basically, the deletion can be divided into two stages:
7+
8+
Search for a node to remove.
9+
If the node is found, delete the node.
10+
Note: Time complexity should be O(height of tree).
11+
12+
Example:
13+
14+
root = [5,3,6,2,4,null,7]
15+
key = 3
16+
17+
5
18+
/ \
19+
3 6
20+
/ \ \
21+
2 4 7
22+
23+
Given key to delete is 3. So we find the node with value 3 and delete it.
24+
25+
One valid answer is [5,4,6,2,null,null,7], shown in the following BST.
26+
27+
5
28+
/ \
29+
4 6
30+
/ \
31+
2 7
32+
33+
Another valid answer is [5,2,6,null,4,null,7].
34+
35+
5
36+
/ \
37+
2 6
38+
\ \
39+
4 7
40+
*/
41+
42+
43+
/**
44+
* Definition for a binary tree node.
45+
* struct TreeNode {
46+
* int val;
47+
* TreeNode *left;
48+
* TreeNode *right;
49+
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
50+
* };
51+
*/
52+
class Solution {
53+
public:
54+
55+
/*由于是BST
56+
1.该结点无孩子:直接删除
57+
2.该节点只有一个孩子:则用该孩子代替被删节点
58+
3.左右孩子均有,需要调整后面所有的树节点
59+
注:需要考虑左右孩子有孩子的情况
60+
难点:删完节点后,还需要是一个二叉搜索树,所以补上的那个节点不一定是其左右孩子节点
61+
*/
62+
63+
64+
/*方法一:递归:
65+
步骤:
66+
1.先可利用BST的左<根<右的特性找到要被删的节点。
67+
2.找到该节点,如果被删节点有一个孩子为空,那么就将另一个不为空的孩子代替即可。
68+
3.如果都不为空,那么可以找到左子树最右的节点或者右子树最左的节点代替被删节点均可以。然后用递归删除最左或者最右的节点即可。
69+
*/
70+
TreeNode* deleteNode(TreeNode* root, int key) {
71+
if (root == NULL)
72+
return NULL;
73+
74+
//找到被删节点
75+
if (root->val > key) {
76+
root->left = deleteNode(root->left, key);
77+
}
78+
else if (root->val < key) {
79+
root->right = deleteNode(root->right, key);
80+
}
81+
else {
82+
//如果找到该节点后,只有一个孩子
83+
if (!root->left || !root->right) {
84+
root = (root->left) ? root->left : root->right;
85+
}
86+
//左右孩子都有
87+
else {
88+
//找到该节点右子树的最左孩子节点(左子树的最右孩子节点也可)
89+
TreeNode* cur = root->right;
90+
while (cur->left) {
91+
cur = cur->left;
92+
}
93+
//用找到的最左孩子节点,替换被删除的节点(其实只是值的替换,并非真的删除节点)
94+
root->val = cur->val;
95+
//然后递归来删除右子树中最左的这个点(实际真的删除了)
96+
root->right = deleteNode(root->right, cur->val); //为什么递归,因为有可能这个最左(右)的节点也可能右孩子
97+
}
98+
}
99+
100+
return root;
101+
}
102+
103+
104+
//方法二:整个都可以使用,而非只是BST
105+
/*
106+
TreeNode* deleteNode(TreeNode* root, int key) {
107+
if (!root)
108+
return NULL;
109+
110+
//判断当找到该节点时
111+
if (root->val == key) {
112+
//这里考虑利用左子树的最右节点代替被删节点
113+
if (root->left) {
114+
TreeNode* cur = root->left;
115+
while(cur->right) {
116+
cur = cur->right;
117+
}
118+
//找到最右点时,交换值即可(被更改的值,在后续递归中会删除)
119+
swap(root->val, cur->val);
120+
}
121+
else {
122+
//如果左子树不存在,直接返回右子树
123+
return root->right;
124+
}
125+
}
126+
127+
//然后循环左右子树
128+
root->left = deleteNode(root->left, key);
129+
root->right = deleteNode(root->right, key);
130+
131+
return root;
132+
}
133+
*/
134+
135+
};

0 commit comments

Comments
 (0)