剑指offer(2)
举例让抽象具体化
栈的压入、弹出序列
题目描述:输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)
1 class Solution { 2 public: 3 //判断popV当前位之前是否有在pushV中排在它之前的数字,有则false,无则true 4 bool IsPopOrder(vector<int> pushV,vector<int> popV) { 5 if(pushV.size()==0 || popV.size()==0) 6 return false; 7 vector<int> st;//用来存储假如顺序 8 for(int i=0,j=0;i<pushV.size();) 9 { 10 st.push_back(pushV[i++]); 11 //一旦发现有与j所在位置相同的数字就向前查找,将相同的数字都排除掉,判断最后st是否为空 12 while(j<popV.size() && popV[j]==st.back()) 13 { 14 st.pop_back(); 15 j++; 16 } 17 } 18 return st.empty(); 19 } 20 };
从上往下打印二叉树
题目描述:从上往下打印出二叉树的每个节点,同层节点从左至右打印。(使用队列操作)
queue模板类的定义在<queue>头文件中。与stack模板类很相似,queue模板类也需要两个模板参数,一个是元素类型,一个容器类型,元素类型是必要的,容器类型是可选的,默认为deque类型。
定义queue对象的示例代码如下:queue<int> q1;queue<double> q2;
queue的基本操作有:
入队,如例:q.push(x); 将x接到队列的末端。
出队,如例:q.pop(); 弹出队列的第一个元素,注意,并不会返回被弹出元素的值。
访问队首元素,如例:q.front(),即最早被压入队列的元素。
访问队尾元素,如例:q.back(),即最后被压入队列的元素。
判断队列空,如例:q.empty(),当队列空时,返回true。
访问队列中的元素个数,如例:q.size()
1 /* 2 struct TreeNode { 3 int val; 4 struct TreeNode *left; 5 struct TreeNode *right; 6 TreeNode(int x) : 7 val(x), left(NULL), right(NULL) { 8 } 9 };*/ 10 class Solution { 11 public: 12 vector<int> PrintFromTopToBottom(TreeNode *root) { 13 vector<int> vec; 14 if(root == NULL) return vec; 15 vec.push_back(root->val); 16 queue<TreeNode*> que; 17 if(root->left != NULL) 18 que.push(root->left); 19 if(root->right != NULL) 20 que.push(root->right); 21 22 while(!que.empty()){ 23 TreeNode* temp = que.front(); 24 que.pop(); 25 26 vec.push_back(temp->val); 27 if(temp->left!=NULL) 28 que.push(temp->left); 29 if(temp->right!=NULL) 30 que.push(temp->right); 31 } 32 return vec; 33 } 34 };
二叉搜索树的后序遍历序列
题目描述:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。
1 class Solution { 2 public: 3 //采用递归方式来求 4 bool isBST(vector<int> que,int m,int n){ 5 if(m>=n) return true; 6 int i=n; 7 while(i--){if(que[i]<que[n]) break;} 8 int l=i; 9 for(;i>=m;i--){if(que[i]>que[n]) break;} 10 if(i>=m) return false; 11 return isBST(que,l,m-1) && isBST(que,l+1,n-1); 12 /*for(;i>-1 && que[i]>que[n];i--); 13 if(i != -1) 14 { 15 int l = i; 16 while(i--){ 17 if(que[i]>que[n]) 18 return false; 19 } 20 return isBST(que,m,l) && isBST(que,l+1,n-1); 21 } 22 return isBST(que,m,n-1);*/ 23 } 24 bool VerifySquenceOfBST(vector<int> sequence) { 25 if(sequence.size()==0) return false; 26 return isBST(sequence,0,sequence.size()-1); 27 //采用简单的非递归方式,每次比较都比较到了sequence[0] 28 /*int n = sequence.size(); 29 while(n--){ 30 int i=n; 31 while(i--){if(sequence[i]<sequence[n]) break;} 32 for(;i>=0;i--){if(sequence[i]>sequence[n]) break;} 33 if(i>=0) return false; 34 } 35 return true;*/ 36 //通过记录当前比较的子树的左边位置,使得每次比较的时候不至于比较到sequence[0] 37 /*int n = sequence.size(); 38 int l=0; 39 while(n--){ 40 int i=n; 41 int j=l; 42 while(i--){if(sequence[i]<sequence[n]) break;} 43 if(i+1<n) l=i+1; 44 else l=0; 45 for(;i>=j;i--){if(sequence[i]>sequence[n]) break;} 46 if(i>=j) return false; 47 } 48 return true;*/ 49 } 50 };
把字符串转换成整数
题目描述:将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数。
1 class Solution { 2 public: 3 int StrToInt(string str) { 4 int temp=0; 5 int i=0; 6 if(str[0] == '-' || str[0] == '+') 7 i++; 8 while(str[i]!='\0') 9 { 10 if(str[i]<'0' || str[i]>'9')//判断是否含有非数字 11 break; 12 temp = temp*10 + (str[i]-'0'); 13 i++; 14 } 15 if(str[i]!='\0')//判断如果含有非数字则返回0 16 return 0; 17 if(str[0] == '-') 18 temp = -temp; 19 return temp; 20 } 21 };
数组中出现次数超过一半的数字(时间效率)
题目描述:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
1 class Solution { 2 public: 3 //关键在超过一半以上 4 int MoreThanHalfNum_Solution(vector<int> numbers) { 5 if(numbers.size()==0) return 0; 6 7 int temp = numbers[0]; 8 int count = 1; 9 for(int i=1;i<numbers.size();i++) 10 { 11 if(temp == numbers[i]) count++; 12 else count--; 13 if(count==0) 14 { 15 temp = numbers[i]; 16 count++; 17 } 18 } 19 count = 0; 20 for(int i=0;i<numbers.size();i++) 21 if(temp == numbers[i]) 22 count++; 23 return count*2>numbers.size()?temp:0; 24 25 } 26 };
还可以使用排序或者Partition,连接:http://blog.csdn.net/yangquanhui1991/article/details/52053995
二叉树中和为某一值的路径(举例让抽象具体化)
题目描述:输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。
1 /* 2 struct TreeNode { 3 int val; 4 struct TreeNode *left; 5 struct TreeNode *right; 6 TreeNode(int x) : 7 val(x), left(NULL), right(NULL) { 8 } 9 };*/ 10 class Solution { 11 public: 12 //递归方式求路径 13 /*vector<vector<int> > res; 14 vector<int> cur; 15 void path(TreeNode* root,int left) 16 { 17 cur.push_back(root->val); 18 if(left-root->val==0 && !root->left &&!root->right) 19 res.push_back(cur); 20 else 21 { 22 if(root->left) path(root->left,left-root->val); 23 if(root->right) path(root->right,left-root->val); 24 } 25 cur.pop_back(); 26 } 27 vector<vector<int> > FindPath(TreeNode* root,int expectNumber) { 28 if(root) path(root,expectNumber); 29 return res; 30 }*/ 31 //非递归 32 vector<vector<int> > FindPath(TreeNode* root,int expectNumber) { 33 vector<vector<int> > res; 34 if (root == NULL) 35 return res; 36 stack<TreeNode *> s; 37 s.push(root); 38 int sum = 0; //当前和 39 vector<int> curPath; //当前路径 40 TreeNode *cur = root; //当前节点 41 TreeNode *last = NULL; //保存上一个节点 42 while (!s.empty()){ 43 if (cur == NULL){ 44 TreeNode *temp = s.top(); 45 if (temp->right != NULL && temp->right != last){ 46 cur = temp->right; //转向未遍历过的右子树 47 }else{ 48 last = temp; //保存上一个已遍历的节点 49 s.pop(); 50 curPath.pop_back(); //从当前路径删除 51 sum -= temp->val; 52 } } 53 else{ 54 s.push(cur); 55 sum += cur->val; 56 curPath.push_back(cur->val); 57 if (cur->left == NULL && cur->right == NULL && sum == expectNumber){ 58 res.push_back(curPath); 59 } 60 cur = cur->left; //先序遍历,左子树先于右子树 61 } 62 } 63 return res; 64 } 65 };
浙公网安备 33010602011771号