144.二叉树的迭代遍历
思路:二叉树的递归遍历很简单就不在赘叙了,下面的代码是广度优先遍历,也不难,就是入栈出栈的操作,感觉和层序挺相似的。
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
stack<TreeNode*> st;
vector<int> res;
if(root==nullptr){
return res;
}
st.push(root);
while(!st.empty()){
TreeNode* node=st.top();
st.pop();
res.push_back(node->val);
if(node->right)
st.push(node->right);
if(node->left)
st.push(node->left);
}
return res;
}
};
145.二叉树的后序(迭代)
思路:也很简单,后序遍历是左右根,而前序遍历是根左右,也就是说将前序遍历翻转,变成右左根,然后调整后序遍历左右根节点入栈的顺序就好了。
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
stack<TreeNode*> st;
vector<int> res;
if(root==nullptr){
return res;
}
st.push(root);
while(!st.empty()){
TreeNode* node=st.top();
st.pop();
res.push_back(node->val);
if(node->left)
st.push(node->left);
if(node->right)
st.push(node->right);
}
reverse(res.begin(),res.end());
return res;
}
};
94.二叉树中序遍历
思路:与前序和后序不同,但总体思想很像,先遍历到二叉树的最左侧节点,并将其压入栈中,当遇到空节点时,弹出栈,放进动态数组中,然后让当前节点指向右侧,继续之前的判断。
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
stack<TreeNode*> st;
vector<int> res;
TreeNode* cur=root;
while(!st.empty()||cur!=nullptr){
if(cur!=nullptr){
st.push(cur);
cur=cur->left;
}else{
cur=st.top();
st.pop();
res.push_back(cur->val);
cur=cur->right;
}
}
return res;
}
};
102.二叉树的层序遍历
思路:二叉树的层序遍历我们用到的数据结构是队列,因为队列是先进先出的数据结构,满足题目要求,首先将根节点放入队列中,判断左右节点是否为空,若不为空则加入队列中,每次遍历完一个循环则要将其放入vec中的元素放入二维数组中。要注意,size的大小,因为size是动态变化的。
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> result;
queue<TreeNode*> que;
if(root==nullptr){
return result;
}
que.push(root);
while(!que.empty()){
int size=que.size();
vector<int> vec;
for(int i=0;i<size;i++){
TreeNode* node=que.front();
que.pop();
vec.push_back(node->val);
if(node->left)
que.push(node->left);
if(node->right)
que.push(node->right);
}
result.push_back(vec);
}
return result;
}
};
151.翻转字符串
思路:1.移除多余空格:采用双指针法移除空格,快指针先移动,当指向不为空且slow不是第一个位置时,将当前位置置为空格,slow递增(因为字符串的首尾位置不能为‘ ’),否则,将fast指向的字符赋值给slow指向的位置,直到fast再次指向空。最后,根据slow的大小调整s字符串的大小。
2.将整个字符串反转:这个函数简单,用到了库函数swap,该函数的作用是-根据已知的字符串的头和尾位置,将其翻转。
3.将每个单词反转:核心函数,先移除空格,在将整个字符串翻转,此时的字符串就是如下图所示
然后,定义一个start=0标记首字符位置,遍历s这个字符串,当i指向空的时候,i-1,此时的i-1就是指向第一个字符串的末尾位置,然后调用翻转函数翻转,将start设置为i+1,为指向下一个字符串的首字符,继续遍历。
class Solution {
public:
void reverse(string& s,int start,int end){
for(int i=start,j=end;i<j;i++,j--){
swap(s[i],s[j]);
}
}
public:
void removeSpace(string& s){
int slow=0;
for(int fast=0;fast<s.size();fast++){
if(s[fast]!=' '){
if(slow!=0){
s[slow++]=' ';
}
while(fast<s.size()&&s[fast]!=' '){
s[slow++]=s[fast++];
}
}
}
s.resize(slow);
}
public:
string reverseWords(string s) {
removeSpace(s);
reverse(s,0,s.size()-1);
int start=0;
for(int i=0;i<=s.size();i++){
if(i==s.size()||s[i]==' '){
reverse(s,start,i-1);
start=i+1;
}
}
return s;
}
};
二叉树的统一迭代也是需要掌握一下,明天补上