剑指offer第四章
剑指offer第四章
1.二叉树的镜像
二叉树的镜像:输入一个二叉树,输出它的镜像
分析:求树的镜像过程其实就是在遍历树的同时,交换非叶结点的左右子结点。
求镜像的过程:先前序遍历这棵树的每个结点,如果遍历到的结点有子结点,交换它的两个子结点,当交换完所有非叶子结点的左右子结点之后,就得到了树的镜像。
- /*
- struct TreeNode {
- int val;
- struct TreeNode *left;
- struct TreeNode *right;
- TreeNode(int x) :
- val(x), left(NULL), right(NULL) {
- }
- };*/
- class Solution {
- public:
- void Mirror(TreeNode *pRoot)
- {
- if(pRoot==NULL)//二叉树为空
- return;
- if(pRoot->left==NULL&&pRoot->right==NULL)//二叉树只有一个结点
- return;
- //交换左右结点
- TreeNode *pTemp=pRoot->left;
- pRoot->left=pRoot->right;
- pRoot->right=pTemp;
- if(pRoot->left) //递归求左子树的镜像
- Mirror(pRoot->left);
- if(pRoot->right)//递归求右子树的镜像
- Mirror(pRoot->right);
- }
- };
2.顺时针打印矩阵
- class Solution {
- public:
- vector<int> printMatrix(vector<vector<int> > matrix) {
- vector<int>res;
- res.clear();
- int rows=matrix.size();//行数
- int columns=matrix[].size();//列数
- //计算打印的圈数
- int circle=((rows<columns?rows:columns)-)/+;//圈数
- for(int i=;i<circle;i++){
- //从左向右打印
- for(int j=i;j<columns-i;j++)
- res.push_back(matrix[i][j]);
- //从上往下的每一列数据
- for(int k=i+;k<rows-i;k++)
- res.push_back(matrix[k][columns--i]);
- //判断是否会重复打印(从右向左的每行数据)
- for(int m=columns-i-;(m>=i)&&(rows-i-!=i);m--)
- res.push_back(matrix[rows-i-][m]);
- //判断是否会重复打印(从下往上的每一列数据)
- for(int n=rows-i-;(n>i)&&(columns-i-!=i);n--)
- res.push_back(matrix[n][i]);}
- return res;
- }
- };
3.包含min函数的栈
定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数。
- /*
- * 1.dataStack为存储数据的栈,minStack为存储最小值的栈;
- * 2.push的时候将value值与minStack中的top值比较,小则minStack push value,大则push top值
- */
- class Solution {
- public:
- stack<int> dataStack, minStack;//定义两个栈,一个数据栈,一个最小值的辅助栈
- void push(int value)
- {
- dataStack.push(value);//将数据进行压入数据栈
- if (minStack.empty()) //如果辅助栈尾空,将数据压入辅助栈
- {
- minStack.push(value);
- }
- else//如果数据小于min,数据压入辅助栈,否则最小值压入辅助栈
- {
- int min = minStack.top();
- value<=min?minStack.push(value):minStack.push(min);
- }
- }
- void pop() //出栈
- {
- dataStack.pop();//数据栈出栈
- minStack.pop();//辅助栈出栈
- }
- int top() //栈顶
- {
- return dataStack.top();
- }
- int min() //取最小
- {
- return minStack.top();
- }
- };
4、栈的压入、弹出序列
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)
- class Solution {
- public:
- bool IsPopOrder(vector<int> pushV,vector<int> popV)
- {
- if(pushV.empty() || popV.empty() || pushV.size()!=popV.size())//如果压入序列或者弹出序列为空、或者压入序列和弹出序列大小不等
- return false;
- stack<int> s;
- int j=;
- for(int i=;i<pushV.size();++i)
- {
- s.push(pushV[i]);
- while(!s.empty()&&s.top()==popV[j])
- {
- s.pop();
- ++j;
- }
- }
- if(s.empty())
- return true;
- return false;
- }
- };
5.从上往下打印二叉树从上往下打印出二叉树的每个节点,同层节点从左至右打印。
- class Solution {
- public:
- vector<int> PrintFromTopToBottom(TreeNode *root)
- {
- queue<TreeNode*> q;
- q.push(root);
- vector<int> r;
- while(!q.empty())
- {
- root = q.front();
- q.pop();
- if(!root)
- continue;
- r.push_back(root -> val);
- q.push(root -> left);
- q.push(root -> right);
- }
- return r;
- }
- };
6.二叉搜索树的后序遍历序列输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。
- class Solution {
- public:
- bool VerifySquenceOfBST(vector<int> sequence) {
- vector<int> leftTree,rightTree;
- int root; // 根结点
- if(sequence.empty())
- return false;
- int index = ; // 标记左右子树界限
- int len = sequence.size();
- root = sequence[len-];
- int i=;
- for(;i<len-;++i)
- {
- if(sequence[i]>root)
- break; // 找到第一个大于根结点的位置,则左边为左子树,右边为右子树
- }
- for(int j=i;j<len-;++j) // 循环时去除root,因此为len-1
- {
- if(sequence[j]<root)
- return false; // 有一个小于root,则返回false
- }
- if(i!=)
- {
- // 即有左子树
- for(int m=;m<i;++m)
- {
- leftTree.push_back(sequence[m]);
- }
- }
- if(i!=len-)
- {
- for(int j=i;j<len-;++j)
- {
- rightTree.push_back(sequence[j]);
- }
- }
- bool left = true,right = true; // 看左右子树是否是二叉搜索树
- if(leftTree.size()>) VerifySquenceOfBST(leftTree);
- if(rightTree.size()>) VerifySquenceOfBST(rightTree);
- return (left&&right);
- }
- };
7.二叉树中和为某一值的路径: 注:路径是从根结点出发到叶结点。
- /*
- struct TreeNode {
- int val;
- struct TreeNode *left;
- struct TreeNode *right;
- TreeNode(int x) :
- val(x), left(NULL), right(NULL) {
- }
- };*/
- class Solution {
- public:
- vector<vector<int> > FindPath(TreeNode* root,int expectNumber)
- {
- vector<vector<int> > res;
- if (root == NULL)
- return res;
- stack<TreeNode *> s;
- s.push(root);
- int sum = ; //当前和
- vector<int> curPath; //当前路径
- TreeNode *cur = root; //当前节点
- TreeNode *last = NULL; //保存上一个节点
- while (!s.empty())
- {
- if (cur == NULL)
- {
- TreeNode *temp = s.top();
- if (temp->right != NULL && temp->right != last)
- {
- cur = temp->right; //转向未遍历过的右子树
- }
- else
- {
- last = temp; //保存上一个已遍历的节点
- s.pop();
- curPath.pop_back(); //从当前路径删除
- sum -= temp->val;
- }
- }
- else
- {
- s.push(cur);
- sum += cur->val;
- curPath.push_back(cur->val);
- if (cur->left == NULL && cur->right == NULL && sum == expectNumber)
- {
- res.push_back(curPath);
- }
- cur = cur->left; //先序遍历,左子树先于右子树
- }
- }
- return res;
- }
- };
8.复杂链表的复制
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。
(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
- /*
- struct RandomListNode {
- int label;
- struct RandomListNode *next, *random;
- RandomListNode(int x) :
- label(x), next(NULL), random(NULL) {
- }
- };
- */
- class Solution {
- public:
- void CloneNodes(RandomListNode* pHead)
- {
- RandomListNode* pNode=pHead;
- while(pNode!=NULL){
- RandomListNode* pCloned=new RandomListNode();
- pCloned->label=pNode->label;
- pCloned->next=pNode->next;
- pCloned->random=NULL;
- pNode->next=pCloned;
- pNode=pCloned->next;
- }
- }
- void ConnectSiblingNodes(RandomListNode* pHead)
- {
- RandomListNode* pNode=pHead;
- while(pNode!=NULL){
- RandomListNode* pCloned=pNode->next;
- if(pNode->random!=NULL)
- {
- pCloned->random=pNode->random->next;
- }
- pNode=pCloned->next;
- }
- }
- RandomListNode* ReconnectNodes(RandomListNode* pHead)
- {
- RandomListNode* pNode=pHead;
- RandomListNode* pClonedHead=NULL;
- RandomListNode* pClonedNode=NULL;
- if(pNode!=NULL)
- {
- pClonedHead=pClonedNode=pNode->next;
- pNode->next=pClonedNode->next;
- pNode=pNode->next;
- }
- while(pNode!=NULL)
- {
- pClonedNode->next=pNode->next;
- pClonedNode=pClonedNode->next;
- pNode->next=pClonedNode->next;
- pNode=pNode->next;
- }
- return pClonedHead;
- }
- RandomListNode* Clone(RandomListNode* pHead)
- {
- CloneNodes(pHead);
- ConnectSiblingNodes(pHead);
- return ReconnectNodes(pHead);
- }
- };
9.二叉搜索树与双向链表
输入一颗二叉搜索树,将该二叉搜索树转换成一个排序的双向链表(要求不能创建新的结点,只能调整树中结点指针的指向)
- /*
- struct TreeNode {
- int val;
- struct TreeNode *left;
- struct TreeNode *right;
- TreeNode(int x) :
- val(x), left(NULL), right(NULL) {
- }
- };*/
- class Solution {
- public:
- void ConvertNode(TreeNode* pNode,TreeNode** pLastNodeInList)
- {
- if(pNode==NULL)
- return;
- TreeNode *pCurrent=pNode;
- if(pCurrent->left!=NULL)
- ConvertNode(pCurrent->left,pLastNodeInList);
- pCurrent->left=*pLastNodeInList;
- if(*pLastNodeInList!=NULL)
- (*pLastNodeInList)->right=pCurrent;
- *pLastNodeInList=pCurrent;
- if(pCurrent->right!=NULL)
- ConvertNode(pCurrent->right,pLastNodeInList);
- }
- TreeNode* Convert(TreeNode* pRootOfTree)
- {
- TreeNode *pLastNodeInList=NULL;
- ConvertNode(pRootOfTree,&pLastNodeInList);
- TreeNode *pHeadOfList=pLastNodeInList;
- while(pHeadOfList!=NULL&&pHeadOfList->left!=NULL)
- pHeadOfList=pHeadOfList->left;
- return pHeadOfList;
- }
- };
10.字符串的排列
输入描述:输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。
- class Solution {
- public:
- set<string> res;
- void fun(string str, int pos)
- {
- if (pos == str.length())
- {
- res.insert(str);
- return;
- }
- for (int i = pos; i < str.length(); ++i)
- {
- swap(str[i], str[pos]);
- fun(str, pos + );
- swap(str[i], str[pos]);
- }
- }
- vector<string> Permutation(string str) {
- res.clear();
- vector<string> st;
- if (str.length() == )
- return st;
- fun(str, );
- set<string>::iterator it;
- for (it = res.begin(); it != res.end(); ++it)
- st.push_back(*it);
- return st;
- }
- };
剑指offer第四章的更多相关文章
- 剑指offer第七章&第八章
剑指offer第七章&第八章 1.把字符串转换成整数 将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数. 数值为0或者字符串不是一个合法的数值则返回0 输入描述: 输入一个字符串 ...
- 剑指offer第六章
剑指offer第六章 1.数字在排序数组中出现的次数 统计一个数字在排序数组中出现的次数.例如输入排序数组{1,2,3,3,3,3,4,5}和数字3,由于3在数组中出现了4次,所以输出4 分析:思路1 ...
- 剑指offer第五章
剑指offer第五章 1.数组中出现次数超过一半的数 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字. 例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组 ...
- 剑指offer第三章
剑指offer第三章 1.数值的整数次方 给定一个double类型的浮点数base和int类型的整数exponent.求base的exponent次方. class Solution { public ...
- JS 剑指Offer(四) 从尾到头打印链表
题目:输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回). 首先定义一下链表中的节点,关于链表这个数据结构在另外一篇文章中会详细讲 function ListNode(val) { t ...
- 《剑指Offer》第二章(一)题3-8
为春招实习做准备,记录一下<剑指Offer>里面的面试题 第二章 面试题3:数组之中的重复数字. 这个题吧,虽然不难,但是不知道为什么就是看了很久,可能很久没有做算法题了.最后面一句话说的 ...
- 《剑指Offer》第二章(一)题 9 -12
第二章 面试题9:用两个栈实现队列 题目:如面试题,给你两个栈, 实现队列的先进先出,即在队列头删除一个元素以及在队列的尾部添加一个元素 思路:这个题的分析感觉很巧妙,从一个具体的例子入手,找出其中的 ...
- 算法学习之剑指offer(四)
题目1 题目描述 输入两棵二叉树A,B,判断B是不是A的子结构.(ps:我们约定空树不是任意一个树的子结构) /** public class TreeNode { int val = 0; Tree ...
- 剑指offer—第三章高质量代码(o(1)时间删除链表节点)
题目:给定单向链表的头指针和一个节点指针,定义一个函数在O(1)时间删除该节点,链表节点与函数的定义如下:struct ListNode{int m_nValue;ListNode* m_pValue ...
随机推荐
- 面向对象-PHP面向对象的特性
1.类和公有化 class Computer { //什么叫做类内,就是创建类的花括号内的范围叫做类内,其他地方则类外. //public 是对字段的公有化,这个字段类外即可访问,赋 ...
- 【程序员笔试面试必会——排序②】Python实现 计数排序、基数排序
一.计数排序 概要: 时间复杂度O(n),空间复杂度O(k),k是输入序列的值的范围(最大值-最小值),是稳定的.计数排序一般用于已知输入值的范围相对较小,比如给公司员工的身高体重信息排序. 思路: ...
- dom&bom的起源,方法,内容,应用
Document Object Model的历史可以追溯至1990年代后期微软与Netscape的"浏览器大战"(browser wars),双方为了在JavaScript与JSc ...
- HDU 4274 Spy's Work (树形DP)
题意 给定一棵树,给出一些子树的权值关系,问是否矛盾(初始所有结点的下限为1) 思路 设lmin和lmax表示题目给定的限制范围,默认为[1..oo]:amin和amax表示实际符合要求的范围.从根节 ...
- Testing shell commands from Python
如何测试shell命令?最近,我遇到了一些情况,我想运行shell命令进行测试,Python称为万能胶水语言,一些自动化测试都可以完成,目前手头的工作都是用python完成的.但是无法从Python中 ...
- 5G信令(就是用户身份信息)——手机开机后,先从USIM中读取之前运营商分配的临时身份信息GUTI/TMSI,发送携带该身份信息的信令给基站,请求接入运营商网络。
5G时代,跟IMSI-CATCHER SAY GOODBYE from:https://unicorn.360.com/blog/2018/04/18/GoodBye_5G_IMSI-Catcher/ ...
- map、filter、reduce、lambda
一.map.filter.reduce map(fuction , iterable) 映射 对可迭代对象中的每一项,使用函数去改变 filter(function, iterable) 过滤 可迭代 ...
- Sql sever 事务
SQL事务 一.事务概念 事务是一种机制.是一种操作序列,它包含了一组数据库操作命令,这组命令要么全部执行,要么全部不执行.因此事务是一个不可分割的工作逻辑单元.在数据库系统上执行并发操作时事务 ...
- git重要命令
body, table{font-family: 微软雅黑; font-size: 13.5pt} table{border-collapse: collapse; border: solid gra ...
- 《Effective C++》第4章 设计与声明(1)-读书笔记
章节回顾: <Effective C++>第1章 让自己习惯C++-读书笔记 <Effective C++>第2章 构造/析构/赋值运算(1)-读书笔记 <Effecti ...