剑指offer之3/6

1. 二叉树的镜像
思路:先前序遍历树的每一个节点,如果遍历的节点有子节点,就交换他的两个子节点,当交换完所有非叶子节点的左右结点之后,就得到了树的镜像。(典型的使用递归求解)

2.对称的二叉树
思路:通过比较二叉树的前序遍历序列和对称前序遍历序列来判断二叉树是不是对称的
其实就是比较左结点是否等于右结点。

3.顺时针打印矩阵
思路:主要是找出四个边界,对于一个mn的矩阵来说,让打印的循环继续下去的条件是
m>2
startX ,n>2*startY。
首先(1)从左到右打印,这一项肯定得有,从startX开始,一直到最后一行
(2)从上到下打印,这一项在多于两行的时候要用到,
(3)从右到左打印,这一项至少矩阵有两行两列时才能打印
(4)从下到上打印,这一项至少矩阵有三行两列才需要

4.包含min的栈
思路:为了实现复杂度为O(1),采用用空间换时间的方法,使用辅助栈。

stack<int> a;
        stack<int> b;
    void push(int value) 
    {
        a.push(value);
        if(b.empty())
            b.push(value);
        else if(b.top()>=value)
            b.push(value);
        else
            b.push(b.top());
        return;
    }
    void pop() 
    {
        if(!a.empty()&&!b.empty())
        {
           a.pop();
           b.pop();
        } 
            return;
    }
    int top() 
    {
        return a.top();
    }
    int min() 
    {
        return b.top();
        
    }

5.栈的压入,弹出序列
思路:使用一个辅助栈,栈顶元素如果与压出栈的栈顶相等,两个栈都弹出,如果不相等,按照压入序列,把数据依次压入辅助栈,直到栈顶等于压出栈的栈顶。如果压入序列所有的数据都已经被压入了辅助栈而依旧没能与压出栈栈顶相等,则返回false.

6.从上到下打印二叉树
思路:先进先出,考虑使用一个辅助队列。根节点先进队列,然后是根节点的左结点,然后是根节点的右结点。然后跟结点出队,然后是左结点的左右子节点入队,左结点出对,右结点出队,右结点的左右子节点入队。

7.二叉搜索树的后序遍历序列
思路:找出后序遍历的特点,后序遍历,最后一位是根节点,前面的数字可以分为两部分,一部分是左子树的值,他们都比根节点小,一部分是右子树的值,他们都比根节点大。 在左子树中不能出现比根节点大的节点,右子树中不能出现比根节点小的节点。 对左子树和右子树再使用递归判断

8.二叉树中和为某一值的路径
使用一个辅助向量vector,保存走过的路径节点,当到达叶子节点,且路径和等于输入参数时,这就是一条路径。 当到达叶子节点但是和不等于输入参数时,删除vector的该叶子节点,回溯

vector<vector<int>> paths;
    vector<int> temp;
    vector<vector<int> > FindPath(TreeNode* root,int expectNumber) 
    {
        if(root!=nullptr)
         Find(root,expectNumber);
        return paths;
    }
    void Find(TreeNode* r,int expectNumber)
    {
        temp.push_back(r->val);
        if(expectNumber-r->val==0 && !r->left && !r->right ) ///已经到叶子节点,切路径相加等于输入数字
            paths.push_back(temp);
        else
        {
           if(r->left)
            Find(r->left,expectNumber-r->val);
           if(r->right)
            Find(r->right,expectNumber-r->val);
        }
        temp.pop_back();
    }

9.复杂链表的复制
思路:分三步
(1)复制链表的每一个节点在自己后面
(2)设置复制出来节点的random
(3)拆分链表

10.二叉搜索树与双向链表
思路:在搜索二叉树中,左子节点总小于父节点,右子节点总大于父节点,那么在双向链表中就让父节点的左节点为左子节点,右节点为右子节点。使用递归

 TreeNode* Convert(TreeNode* pRootOfTree)
    {
        TreeNode* LastNode=nullptr; ///指向最后一个节点的指针的指针
        convertNode(pRootOfTree,LastNode);
        TreeNode* head=LastNode;
        while(head!=NULL&&head->left!=nullptr) ///遍历找到头结点
            head=head->left;
        return head;
    }
    void convertNode(TreeNode* node,TreeNode* &LastNode) ///这个第二个参数&要注意
    {
        if(node==NULL)
            return;
        TreeNode* current=node;
        if(current->left!=nullptr)
            convertNode(current->left,LastNode);
        current->left=LastNode;
        if(LastNode!=nullptr)
            LastNode->right=current;
       LastNode=current;
        if(current->right!=nullptr)
        {
            convertNode(current->right,LastNode);
        }
    }

11.序列化二叉树(不懂)
思路:根据前序遍历顺序来序列化一个二叉树,

12.字符串的排序
思路:把一个字符串看成两部分,第一个字符,和后面的字符。分别把第一个字符和后面的每一个字符交换。再把后面的字符再分成两部分,交换
在这里插入图片描述

Guess you like

Origin blog.csdn.net/weixin_39373577/article/details/89666652