forked from keineahnung2345/leetcode-cpp-practices
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path100. Same Tree.cpp
143 lines (108 loc) · 3.71 KB
/
100. Same Tree.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/**
Given two binary trees, write a function to check if they are the same or not.
Two binary trees are considered the same if they are structurally identical and the nodes have the same value.
Example 1:
Input: 1 1
/ \ / \
2 3 2 3
[1,2,3], [1,2,3]
Output: true
Example 2:
Input: 1 1
/ \
2 2
[1,2], [1,null,2]
Output: false
Example 3:
Input: 1 1
/ \ / \
2 1 1 2
[1,2,1], [1,1,2]
Output: false
**/
//Runtime: 4 ms, faster than 100.00% of C++ online submissions for Same Tree.
//Memory Usage: 9.7 MB, less than 99.45% of C++ online submissions for Same Tree.
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool isSameTree(TreeNode* p, TreeNode* q) {
if(p == NULL && q == NULL){
return true;
}else if(p != NULL && q == NULL){
return false;
}else if(p == NULL && q != NULL){
return false;
}
return p->val == q->val && isSameTree(p->left, q->left) && isSameTree(p->right, q->right);
}
};
/**
Approach 1: Recursion
Intuition
The simplest strategy here is to use recursion. Check if p and q nodes are not None, and their values are equal. If all checks are OK, do the same for the child nodes recursively.
**/
/**
Complexity Analysis
Time complexity : \mathcal{O}(N)O(N), where N is a number of nodes in the tree, since one visits each node exactly once.
Space complexity : \mathcal{O}(\log(N))O(log(N)) in the best case of completely balanced tree and \mathcal{O}(N)O(N) in the worst case of completely unbalanced tree, to keep a recursion stack.
**/
/**
Approach 2: Iteration
Intuition
Start from the root and then at each iteration pop the current node out of the deque. Then do the same checks as in the approach 1 :
p and p are not None,
p.val is equal to q.val,
and if checks are OK, push the child nodes.
**/
/**
Complexity Analysis
Time complexity : \mathcal{O}(N)O(N) since each node is visited exactly once.
Space complexity : \mathcal{O}(\log(N))O(log(N)) in the best case of completely balanced tree and \mathcal{O}(N)O(N) in the worst case of completely unbalanced tree, to keep a deque.
**/
/**
class Solution {
public:
bool check(TreeNode* p, TreeNode* q){
//this function check current node
if(p == NULL && q == NULL) return true;
if(p == NULL || q == NULL) return false;
if(p->val != q->val) return false;
return true;
}
bool isSameTree(TreeNode* p, TreeNode* q) {
//if check returns true, there are two cases needed to be handled differently
//if check returns false, just return false
if(p == NULL && q == NULL) return true;
if(!check(p, q)) return false;
queue<TreeNode*> q1, q2;
q1.push(p);
q2.push(q);
while(!q1.empty()){
p = q1.front(); q1.pop();
q = q2.front(); q2.pop();
if(p == NULL && q == NULL) continue;
if(!check(p, q)) return false;
//now both p and q are not NULL
if(!check(p->left, q->left)) return false;
if(p->left != NULL){
q1.push(p->left);
q2.push(q->left);
}
if(!check(p->right, q->right)) return false;
if(p->right != NULL){
q1.push(p->right);
q2.push(q->right);
}
}
return true;
}
};
**/