第一题:二维数组的查找
题目描述
在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
题解:
由于二维数组数从左到右递增,从上到下递增,那么,我们可以考虑从左下角查找,如果val大于array[i][j]的话,j++,如果小于a[i][j]的话,i--,否则输出true表示找到了val;
如果到最后都没有找到,说明不存在该元素,返回false:表示没有该元素。
参考代码:
1 class Solution {
2 public:
3 bool Find(int target, vector<vector<int> > array) {
4 // array是二维数组,这里没做判空操作
5 int rows = array.size();
6 int cols = array[0].size();
7 int i=rows-1,j=0;//左下角元素坐标
8 while(i>=0 && j<cols){//使其不超出数组范围
9 if(target<array[i][j])
10 i--;//查找的元素较少,往上找
11 else if(target>array[i][j])
12 j++;//查找元素较大,往右找
13 else
14 return true;//找到
15 }
16 return false;
17 }
18 };
C++
第二题:替换空格
题目描述
请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。
题解:
我们先统计出来空格的数量,计算出替换后的字符串的长度,然后从后往前替换即可。
参考代码:
View Code
1 public class Solution {
2 public String replaceSpace(StringBuffer str) {
3 return str.toString().replaceAll("\\s", "%20");
4 }
5 }
View Code
第三题:从尾到头打印字符
题目描述
输入一个链表,按链表从尾到头的顺序返回一个ArrayList。
题解:
每次插入到vector的头部直到head==NULL;
参考代码:
1 /**
2 * struct ListNode {
3 * int val;
4 * struct ListNode *next;
5 * ListNode(int x) :
6 * val(x), next(NULL) {
7 * }
8 * };
9 */
10 class Solution {
11 public:
12 vector<int> printListFromTailToHead(ListNode* head)
13 {
14 vector<int> ans;
15 while(head!=NULL)
16 {
17 ans.insert(ans.begin(),head->val);
18 head=head->next;
19 }
20 return ans;
21
22 }
23 };
C++
第四题:重建二叉树
题目描述
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
题解:
例如:前序遍历 GDAFEMHZ
中序遍历 ADEFGHMZ
则根据前序遍历规则知道树根为G,那么我们在中序遍历中找到根,那么根G 左边的一定是该根的左子树的节点,根右边的元素一定是根右子树的节点;
我们这样递归即可得到原二叉树。
参考代码:
1 /**
2 * Definition for binary tree
3 * struct TreeNode {
4 * int val;
5 * TreeNode *left;
6 * TreeNode *right;
7 * TreeNode(int x) : val(x), left(NULL), right(NULL) {}
8 * };
9 */
10 class Solution {
11 public:
12 TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
13 if(pre.size()==0||pre.size()!=vin.size()) return NULL;
14
15 vector<int> pre_left,pre_right;
16 vector<int> inl,inr;
17 TreeNode *node=new TreeNode(pre[0]);
18 int rootindex;
19 //找到中序遍历数组中根的位置
20 for(int i=0;i<vin.size();++i)
21 {
22 if(vin[i]==pre[0])
23 {
24 rootindex=i;
25 break;
26 }
27 }
28 //左子树元素
29 for(int i=0;i<rootindex;++i)
30 {
31 inl.push_back(vin[i]);
32 if(i+1<pre.size()) pre_left.push_back(pre[i+1]);
33 }
34 //右子树元素
35 for(int i=rootindex+1;i<vin.size();++i)
36 {
37 inr.push_back(vin[i]);
38 pre_right.push_back(pre[i]);
39 }
40
41 node->left=reConstructBinaryTree(pre_left,inl);
42 node->right=reConstructBinaryTree(pre_right,inr);
43
44 return node;
45 }
46 };
C++
1 /**
2 * Definition for binary tree
3 * public class TreeNode {
4 * int val;
5 * TreeNode left;
6 * TreeNode right;
7 * TreeNode(int x) { val = x; }
8 * }
9 */
10 public class Solution {
11 public TreeNode reConstructBinaryTree(int [] pre,int [] in)
12 {
13 TreeNode node=func(pre,0,pre.length-1,in,0,in.length-1);
14 return node;
15 }
16 public TreeNode func(int [] pre,int pre_start,int pre_end,int [] in,int in_start,int in_end)
17 {
18 if(pre_start>pre_end||in_start>in_end)
19 {
20 return null;
21 }
22 TreeNode node = new TreeNode(pre[pre_start]);
23
24 for(int i=in_start;i<=in_end;++i)
25 {
26 if(in[i]==pre[pre_start])
27 {
28 node.left=func(pre,pre_start+1,pre_start+i-in_start,in,in_start,i-1);
29 node.right=func(pre,pre_start+i-in_start+1,pre_end,in,i+1,in_end);
30
31 break;
32 }
33 }
34 return node;
35 }
36 }
Java
第五题:用两个栈来实现一个队列
题目描述
用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。
题解:
对于push操作,我们直接放入stack1中,对于pop操作,我们先判断stack2是否空,不空就输出stack2的栈顶元素即可;为空就把stack1中的元素放入到stack2中然后输出stack2的栈顶元素;
参考代码:
1 class Solution
2 {
3 public:
4 void push(int node) {
5 stack1.push(node);
6 }
7
8 int pop() {
9 int ans;
10 if(!stack2.empty())
11 ans=stack2.top(),stack2.pop();
12 else
13 {
14 while(!stack1.empty())
15 {
16 stack2.push(stack1.top());
17 stack1.pop();
18 }
19 ans=stack2.top(),stack2.pop();
20 }
21 return ans;
22 }
23
24 private:
25 stack<int> stack1;
26 stack<int> stack2;
27 };
C++
1 import java.util.Stack;
2
3 public class Solution {
4 Stack<Integer> stack1 = new Stack<Integer>();
5 Stack<Integer> stack2 = new Stack<Integer>();
6
7 public void push(int node) {
8 stack1.push(node);
9 }
10
11 public int pop() {
12 if(!stack2.empty())
13 return stack2.pop();
14 else
15 {
16 while(!stack1.empty())
17 {
18 stack2.push(stack1.pop());
19 }
20 return stack2.pop();
21 }
22 }
23 }
Java
第六题:旋转数组最小的数字
题目描述
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。
例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。
NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
题解:
就是找数组的最小值。
参考代码:
1 class Solution {
2 public:
3 int minNumberInRotateArray(vector<int> array) {
4 if(!array.size()) return 0;
5 int ans=array[0];
6 for(int i=1;i<array.size();++i)
7 ans=min(ans,array[i]);
8 return ans;
9 }
10 };
C++
1 import java.util.ArrayList;
2 public class Solution {
3 public int minNumberInRotateArray(int [] array) {
4 if(array.length==0) return 0;
5 int ans=array[0];
6 for(int i=1;i<array.length;++i)
7 {
8 if(array[i]<ans) ans=array[i];
9 }
10 return ans;
11
12 }
13 }
Java
第七题:斐波那契数列
题目描述
大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0)。
n<=39
题解:
a[n]=a[n-1]+a[n-2];
参考代码:
1 class Solution {
2 public:
3 int Fibonacci(int n) {
4 int a=1,b=1;
5 if(n==0) return 0;
6 if(n==1||n==2) return 1;
7 for(int i=3;i<=n;++i)
8 {
9 int c=a;
10 a=a+b;
11 b=c;
12 }
13 return a;
14 }
15 };
C++
1 public class Solution {
2 public int Fibonacci(int n) {
3 int a=1,b=1;
4 if(n==0) return 0;
5 if(n==1||n==2) return 1;
6 for(int i=3;i<=n;++i)
7 {
8 int c=a;
9 a=a+b;
10 b=c;
11 }
12 return a;
13 }
14 }
Java
第八题:跳台阶
题目描述
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。
题解:
本质也是斐波那契数列
参考代码:
1 class Solution {
2 public:
3 int jumpFloor(int number) {
4 if(number==1) return 1;
5 if(number==2) return 2;
6 return jumpFloor(number-1)+jumpFloor(number-2);
7 }
8 };
C++
1 public class Solution {
2 public int JumpFloor(int number) {
3 if(number==1) return 1;
4 if(number==2) return 2;
5 return JumpFloor(number-1)+JumpFloor(number-2);
6 }
7 }
Java
第九题:变态跳台阶
题目描述
一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
题解:
和斐波那契数列推导一样,这个推一下吧。
用Fib(n)表示青蛙跳上n阶台阶的跳法数,青蛙一次性跳上n阶台阶的跳法数1(n阶跳),设定Fib(0) = 1;
当n = 1 时,只有一种跳法,即1阶跳:Fib(1) = 1;
当n = 2 时,有两种跳的方式,一阶跳和二阶跳:Fib(2) = Fib(1) + Fib(0) = 2;
当n = 3 时,有三种跳的方式,第一次跳出一阶后,后面还有Fib(3-1)中跳法;第一次跳出二阶后,后面还有Fib(3-2)中跳法;第一次跳出三阶后,后面还有Fib(3-3)中跳法
当n = n 时,共有n种跳的方式,第一次跳出一阶后,后面还有Fib(n-1)中跳法;第一次跳出二阶后,后面还有Fib(n-2)中跳法…第一次跳出n阶后,后面还有 Fib(n-n)中跳法.
Fib(n) = Fib(n-1)+Fib(n-2)+Fib(n-3)+……….+Fib(n-n)=Fib(0)+Fib(1)+Fib(2)+…….+Fib(n-1)
又因为Fib(n-1)=Fib(0)+Fib(1)+Fib(2)+…….+Fib(n-2)
两式相减得:Fib(n) = 2*Fib(n-1) n >= 2
参考代码:
1 class Solution {
2 public:
3 int jumpFloorII(int number) {
4 if(number==0) return 0;
5 int ans=1;
6 for(int i=1;i<number;++i)
7 ans=ans*2;
8 return ans;
9 }
10 };
C++
1 public class Solution {
2 public int JumpFloorII(int number) {
3 if(number==0) return 0;
4 int ans=1;
5 for(int i=1;i<number;++i)
6 ans=ans*2;
7 return ans;
8 }
9 }
Java
第十题:矩形覆盖
题目描述
我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?
题解:
n=1
:只有横放一个矩形一种解决办法n=2
:有横放一个矩形,竖放两个矩形两种解决办法n=3
:n=2
的基础上加1个横向,n=1的基础上加2个竖向n=4
:n=3
的基础上加1个横向,n=2的基础上加2个竖向
...
n=n
:n = f(n-1) + f(n-2)
参考代码:
1 class Solution {
2 public:
3 int rectCover(int n) {
4 if(n==0) return 0;
5 if(n==1) return 1;
6 if(n==2) return 2;
7 int a=2,b=1,c;
8 for(int i=3;i<=n;++i)
9 {
10 c=a;
11 a=a+b;
12 b=c;
13 }
14 return a;
15 }
16 };
C++
1 public class Solution {
2 public int RectCover(int n) {
3 if(n==0) return 0;
4 if(n==1) return 1;
5 if(n==2) return 2;
6 int a=2,b=1,c;
7 for(int i=3;i<=n;++i)
8 {
9 c=a;
10 a=a+b;
11 b=c;
12 }
13 return a;
14 }
15 }
Java
第十一题:二进制中一的个数
题目描述
输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
题解:
每次n&(n-1)即可以把最后一个一取出来;
参考代码:
1 class Solution {
2 public:
3 int NumberOf1(int n) {
4 int ans=0;
5 while(n)
6 {
7 n&=(n-1);
8 ans++;
9 }
10 return ans;
11 }
12 };
C++
1 public class Solution {
2 public int NumberOf1(int n) {
3 int ans=0;
4 while(n!=0)
5 {
6 n&=(n-1);
7 ans++;
8 }
9 return ans;
10 }
11 }
Java
第十二题:数值的整数次方
题目描述
给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。
保证base和exponent不同时为0
题解:
注意正负号,快速幂即可;
参考代码:
1 class Solution {
2 public:
3 double Power(double b, int e) {
4 if(e==0) return 1;
5 if(e==1) return b;
6 double res=1;
7 int tmp=0;
8 if(e<0) e=-e,tmp=1;
9
10 while(e!=0)
11 {
12 if(e&1) res=res*b;
13 b=b*b;
14 e>>=1;
15 }
16 if(tmp==1) res=1.0/res;
17
18 return res;
19 }
20 };
C++
1 public class Solution {
2 public double Power(double b, int ee) {
3 if(ee==0) return 1;
4 if(ee==1) return b;
5 double res=1;
6 int tmp=0;
7 if(ee<0)
8 {
9 ee=-ee;
10 tmp=1;
11 }
12
13 while(ee!=0)
14 {
15 if((ee&1)==1) res=res*b;
16 b=b*b;
17 ee>>=1;
18 }
19 if(tmp==1) res=1.0/res;
20
21 return res;
22 }
23 }
Java
第十三题:调整该数组中数字的顺序
题目描述
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
题解:
我们用 i记录奇数的位置,j表示偶数的左边界,每次遇到一个奇数,就把j~i-1的偶数向后移一位,然后把这个奇数放到第j个位置上,j++;
参考代码:
1 class Solution {
2 public:
3 void reOrderArray(vector<int> &array) {
4 vector<int> t1,t2;
5 int i,j;
6 for(i=0;i<array.size();i++){
7 if(array[i]%2!=0){
8 t1.push_back(array[i]);
9 }else{
10 t2.push_back(array[i]);
11 }
12 }
13 for(i=0;i<t1.size();i++){
14 array[i]=t1[i];
15 }
16 for(j=0;j<t2.size()&&i<array.size();j++,i++){
17 array[i]=t2[j];
18 }
19 }
20 };
C++
1 public class Solution {
2 public void reOrderArray(int[] array) {
3 int j = 0;
4 for (int i = 0; i < array.length; i++) {
5 if (array[i] % 2 == 1) {
6 //如果是奇数的话
7 if (i != j) {
8 int temp = array[i];
9 int k = i;
10 for (k = i; k > j; k--) {
11 array[k] = array[k - 1];
12 }
13 array[k] = temp;
14
15 }
16 j++;
17 }
18 }
19 }
20 }
Java
第十四题:输出链表中倒数第k个结点
题目描述
输入一个链表,输出该链表中倒数第k个结点。
题解:
用快慢指针法,快指针先走k-1步,然后快慢指针一起移动即可。
参考代码:
1 /*
2 struct ListNode {
3 int val;
4 struct ListNode *next;
5 ListNode(int x) :
6 val(x), next(NULL) {
7 }
8 };*/
9 class Solution {
10 public:
11 ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
12 ListNode* p=pListHead;
13 ListNode* q=pListHead;
14 int i=0;
15 for(;p!=NULL;i++)
16 {
17 if(i>=k)
18 q=q->next;
19 p=p->next;
20 }
21 if(i<k)
22 return NULL;
23 else
24 return q;
25 }
26 };
C++
1 /*
2 public class ListNode {
3 int val;
4 ListNode next = null;
5
6 ListNode(int val) {
7 this.val = val;
8 }
9 }*/
10 public class Solution {
11 public ListNode FindKthToTail(ListNode pListHead,int k) {
12 ListNode p=pListHead;
13 ListNode q=pListHead;
14 int i=0;
15 for(;p!=null;i++)
16 {
17 if(i>=k)
18 q=q.next;
19 p=p.next;
20 }
21 if(i<k)
22 return null;
23 else
24 return q;
25 }
26 }
Java
第十五题:反转链表
题目描述
输入一个链表,反转链表后,输出新链表的表头。
题解:
记录3个指针,pre,now,next
pre:表示now的前一个节点,now:表示当前节点,next:表示now的下一个节点(可能为NULL);
每次让
next=now->next;
now->next=pre;
pre=now;
now=next;
结束标志为 now==NULL;
最后输出指针now就行了。
参考代码:
1 /*
2 struct ListNode {
3 int val;
4 struct ListNode *next;
5 ListNode(int x) :
6 val(x), next(NULL) {
7 }
8 };*/
9 class Solution {
10 public:
11 ListNode* ReverseList(ListNode* pHead) {
12 ListNode *reverse=NULL;
13 ListNode *node=pHead;
14 ListNode *pre=NULL;
15 while(node!=NULL)
16 {
17 ListNode *next=node->next;
18 if(next==NULL)
19 reverse=node;
20 node->next=pre;
21 pre=node;
22 node=next;
23 }
24 return reverse;
25 }
26 };
C++
1 public class Solution {
2 public ListNode ReverseList(ListNode head) {
3 ListNode pre = null;
4 ListNode now = head;
5 ListNode aft = null;
6 while(now != null){
7 aft = now.next;
8 now.next=pre;
9 pre = now;
10 now = aft;
11 }
12 return pre;
13 }
14 }
Java
第十六题 反转链表
时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M 热度指数:662243
本题知识点: 链表
题目描述
输入一个链表,反转链表后,输出新链表的表头。
题解:
记录3个指针即可。
参考代码:
public class Solution {
public ListNode ReverseList(ListNode head) {
ListNode pre = null;
ListNode now = head;
ListNode aft = null;
while(now != null){
aft = now.next;
now.next=pre;
pre = now;
now = aft;
}
return pre;
}
}
Java
第十七题 合并两个有序链表
时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M 热度指数:641239
本题知识点: 链表
题目描述
输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
题解:
新建一个链表头。然后依次将两个链表中的元素加入即可,判断一下大小。
参考代码:
public class Solution {
public ListNode Merge(ListNode l1,ListNode l2) {
ListNode l3=new ListNode(0);
ListNode l4=l3;
while(l1!=null && l2!=null)
{
if(l1.val<=l2.val)
{
l3.next=l1;
l1=l1.next;
}
else
{
l3.next=l2;
l2=l2.next;
}
l3=l3.next;
}
if(l1!=null) l3.next=l1;
else if(l2!=null) l3.next=l2;
return l4.next;
}
}
Java
第十八题 树的子结构
时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M 热度指数:617491
本题知识点: 二叉树
题目描述
输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)
题解:
对于树B,要么和root本身相同,要么和root.left相同,要么和root.right相同。否则就不是树A的子结构。
递归判断即可。
参考代码:
/**
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public boolean IsSubtree(TreeNode a,TreeNode b)
{
if(b==null) return true;
if(a==null) return false;
if(a.val==b.val)
{
return IsSubtree(a.left,b.left) && IsSubtree(a.right,b.right);
}
else return false;
}
public boolean HasSubtree(TreeNode root1,TreeNode root2)
{
if(root2==null||root1==null) return false;
return IsSubtree(root1,root2)||HasSubtree(root1.left,root2)||HasSubtree(root1.right,root2);
}
}
Java
第十九题 二叉树镜像
时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M 热度指数:355640
本题知识点: 树
题目描述
操作给定的二叉树,将其变换为源二叉树的镜像。
输入描述:
二叉树的镜像定义:源二叉树
8
/ \
6 10
/ \ / \
5 7 9 11
镜像二叉树
8
/ \
10 6
/ \ / \
11 9 7 5
题解:
水题,递归将左右子树交换即可。
参考代码:
/**
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public void Mirror(TreeNode root)
{
if(root==null) return ;
TreeNode temp=root.left;
root.left=root.right;
root.right=temp;
Mirror(root.left);
Mirror(root.right);
}
}
Java
第二十题 顺时针打印矩阵
时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M 热度指数:652806
本题知识点: 数组
题目描述
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.
题解:
记录左右上下边界,然后依次输出(注意判断是否重合,左右,上下)。
参考代码:
class Solution {
public:
vector<int> printMatrix(vector<vector<int> > matrix)
{
int row = matrix.size();
if(row==0) return {};
int col = matrix[0].size();
vector<int> res;
if (row == 0 || col == 0) return res;
// 定义四个关键变量,表示左上和右下的打印范围
int left = 0, top = 0, right = col - 1, bottom = row - 1;
while (left <= right && top <= bottom)
{
// left to right
for (int i = left; i <= right; ++i) res.push_back(matrix[top][i]);
// top to bottom
for (int i = top + 1; i <= bottom; ++i) res.push_back(matrix[i][right]);
// right to left
if (top != bottom)
for (int i = right - 1; i >= left; --i) res.push_back(matrix[bottom][i]);
// bottom to top
if (left != right)
for (int i = bottom - 1; i > top; --i) res.push_back(matrix[i][left]);
left++,top++,right--,bottom--;
}
return res;
}
};
C++
第二十一题 包含min函数的栈
时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M 热度指数:381435
本题知识点: 栈
题目描述
定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1))。
题解:使用两个栈st,st2.st里面放元素,st2是个单调栈,保存当前栈st中的最小元素。
参考代码:
class Solution {
public:
stack<int> st,st2;
void push(int value)
{
st.push(value);
if(st2.empty() || (value<st2.top()))
st2.push(value);
}
void pop()
{
if(!st.empty())
{
int val=st.top();
st.pop();
if(val==st2.top())
st2.pop();
}
}
int top()
{
if(!st.empty())
return st.top();
}
int min()
{
if(!st2.empty())
return st2.top();
}
};
C++
第二十二题 栈的压入和弹出
题目描述
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列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)
{
stack<int> st;
int id=0;
for(int i=0;i<popV.size();++i)
{
while(st.empty()||st.top()!=popV[i])
{
st.push(pushV[id++]);
if(id>pushV.size())
return false;
}
st.pop();
}
if(st.empty()) return true;
else return false;
}
};
C++
第二十三题 从上往下打印二叉树
题目描述
从上往下打印出二叉树的每个节点,同层节点从左至右打印。
题解:用队列即可。
参考代码:
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
class Solution {
public:
vector<int> PrintFromTopToBottom(TreeNode* root)
{
vector<int> ans;
if(root==NULL) return ans;
queue<TreeNode*> q;
q.push(root);
int cnt=1;
while(!q.empty())
{
TreeNode* u=q.front();q.pop();
ans.push_back(u->val);
if(u->left) q.push(u->left);
if(u->right) q.push(u->right);
}
return ans;
}
};
C++
第二十四题 二叉搜索树的后序遍历序列
题目描述
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。
题解:二叉搜索树的性质:左子树的元素都比根小,右子树的元素都比根大。这样,知道最后一个元素一定是根,然后我们对每一层找到第一个比根大的元素,然后判断后面的是否都比根大,如果有比根小的,则返回false,否则继续判断左右子树,返回true,递归判断。
参考代码:
class Solution {
public:
bool VerifySquenceOfBST(vector<int> sequence) {
return bst(sequence,0,sequence.size()-1);
}
bool bst(vector<int> sequence,int begin,int end)
{
if(sequence.empty()||begin>end)
return false;
int root=sequence[end];
int i=begin;
for(;i<end;++i)
if(sequence[i]>root) break;
for(int j=i;j<end;++j)
if(sequence[j]<root) return false;
bool left=true;
if(i>begin)
left=bst(sequence,begin,i-1);
bool right=true;
if(i<end-1)
right=bst(sequence,i,end-1);
return left&&right;
}
};
C++
未完待续~
题解:
我们先统计出来空格的数量,计算出替换后的字符串的长度,然后从后往前替换即可。
参考代码:
View Code
1 public class Solution {
2 public String replaceSpace(StringBuffer str) {
3 return str.toString().replaceAll("\\s", "%20");
4 }
5 }
View Code
第三题:从尾到头打印字符
题目描述
输入一个链表,按链表从尾到头的顺序返回一个ArrayList。
题解:
每次插入到vector的头部直到head==NULL;
参考代码:
1 /**
2 * struct ListNode {
3 * int val;
4 * struct ListNode *next;
5 * ListNode(int x) :
6 * val(x), next(NULL) {
7 * }
8 * };
9 */
10 class Solution {
11 public:
12 vector<int> printListFromTailToHead(ListNode* head)
13 {
14 vector<int> ans;
15 while(head!=NULL)
16 {
17 ans.insert(ans.begin(),head->val);
18 head=head->next;
19 }
20 return ans;
21
22 }
23 };
C++
第四题:重建二叉树
题目描述
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
题解:
例如:前序遍历 GDAFEMHZ
中序遍历 ADEFGHMZ
则根据前序遍历规则知道树根为G,那么我们在中序遍历中找到根,那么根G 左边的一定是该根的左子树的节点,根右边的元素一定是根右子树的节点;
我们这样递归即可得到原二叉树。
参考代码:
1 /**
2 * Definition for binary tree
3 * struct TreeNode {
4 * int val;
5 * TreeNode *left;
6 * TreeNode *right;
7 * TreeNode(int x) : val(x), left(NULL), right(NULL) {}
8 * };
9 */
10 class Solution {
11 public:
12 TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
13 if(pre.size()==0||pre.size()!=vin.size()) return NULL;
14
15 vector<int> pre_left,pre_right;
16 vector<int> inl,inr;
17 TreeNode *node=new TreeNode(pre[0]);
18 int rootindex;
19 //找到中序遍历数组中根的位置
20 for(int i=0;i<vin.size();++i)
21 {
22 if(vin[i]==pre[0])
23 {
24 rootindex=i;
25 break;
26 }
27 }
28 //左子树元素
29 for(int i=0;i<rootindex;++i)
30 {
31 inl.push_back(vin[i]);
32 if(i+1<pre.size()) pre_left.push_back(pre[i+1]);
33 }
34 //右子树元素
35 for(int i=rootindex+1;i<vin.size();++i)
36 {
37 inr.push_back(vin[i]);
38 pre_right.push_back(pre[i]);
39 }
40
41 node->left=reConstructBinaryTree(pre_left,inl);
42 node->right=reConstructBinaryTree(pre_right,inr);
43
44 return node;
45 }
46 };
C++
1 /**
2 * Definition for binary tree
3 * public class TreeNode {
4 * int val;
5 * TreeNode left;
6 * TreeNode right;
7 * TreeNode(int x) { val = x; }
8 * }
9 */
10 public class Solution {
11 public TreeNode reConstructBinaryTree(int [] pre,int [] in)
12 {
13 TreeNode node=func(pre,0,pre.length-1,in,0,in.length-1);
14 return node;
15 }
16 public TreeNode func(int [] pre,int pre_start,int pre_end,int [] in,int in_start,int in_end)
17 {
18 if(pre_start>pre_end||in_start>in_end)
19 {
20 return null;
21 }
22 TreeNode node = new TreeNode(pre[pre_start]);
23
24 for(int i=in_start;i<=in_end;++i)
25 {
26 if(in[i]==pre[pre_start])
27 {
28 node.left=func(pre,pre_start+1,pre_start+i-in_start,in,in_start,i-1);
29 node.right=func(pre,pre_start+i-in_start+1,pre_end,in,i+1,in_end);
30
31 break;
32 }
33 }
34 return node;
35 }
36 }
Java
第五题:用两个栈来实现一个队列
题目描述
用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。
题解:
对于push操作,我们直接放入stack1中,对于pop操作,我们先判断stack2是否空,不空就输出stack2的栈顶元素即可;为空就把stack1中的元素放入到stack2中然后输出stack2的栈顶元素;
参考代码:
1 class Solution
2 {
3 public:
4 void push(int node) {
5 stack1.push(node);
6 }
7
8 int pop() {
9 int ans;
10 if(!stack2.empty())
11 ans=stack2.top(),stack2.pop();
12 else
13 {
14 while(!stack1.empty())
15 {
16 stack2.push(stack1.top());
17 stack1.pop();
18 }
19 ans=stack2.top(),stack2.pop();
20 }
21 return ans;
22 }
23
24 private:
25 stack<int> stack1;
26 stack<int> stack2;
27 };
C++
1 import java.util.Stack;
2
3 public class Solution {
4 Stack<Integer> stack1 = new Stack<Integer>();
5 Stack<Integer> stack2 = new Stack<Integer>();
6
7 public void push(int node) {
8 stack1.push(node);
9 }
10
11 public int pop() {
12 if(!stack2.empty())
13 return stack2.pop();
14 else
15 {
16 while(!stack1.empty())
17 {
18 stack2.push(stack1.pop());
19 }
20 return stack2.pop();
21 }
22 }
23 }
Java
第六题:旋转数组最小的数字
题目描述
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。
例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。
NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
题解:
就是找数组的最小值。
参考代码:
1 class Solution {
2 public:
3 int minNumberInRotateArray(vector<int> array) {
4 if(!array.size()) return 0;
5 int ans=array[0];
6 for(int i=1;i<array.size();++i)
7 ans=min(ans,array[i]);
8 return ans;
9 }
10 };
C++
1 import java.util.ArrayList;
2 public class Solution {
3 public int minNumberInRotateArray(int [] array) {
4 if(array.length==0) return 0;
5 int ans=array[0];
6 for(int i=1;i<array.length;++i)
7 {
8 if(array[i]<ans) ans=array[i];
9 }
10 return ans;
11
12 }
13 }
Java
第七题:斐波那契数列
题目描述
大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0)。
n<=39
题解:
a[n]=a[n-1]+a[n-2];
参考代码:
1 class Solution {
2 public:
3 int Fibonacci(int n) {
4 int a=1,b=1;
5 if(n==0) return 0;
6 if(n==1||n==2) return 1;
7 for(int i=3;i<=n;++i)
8 {
9 int c=a;
10 a=a+b;
11 b=c;
12 }
13 return a;
14 }
15 };
C++
1 public class Solution {
2 public int Fibonacci(int n) {
3 int a=1,b=1;
4 if(n==0) return 0;
5 if(n==1||n==2) return 1;
6 for(int i=3;i<=n;++i)
7 {
8 int c=a;
9 a=a+b;
10 b=c;
11 }
12 return a;
13 }
14 }
Java
第八题:跳台阶
题目描述
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。
题解:
本质也是斐波那契数列
参考代码:
1 class Solution {
2 public:
3 int jumpFloor(int number) {
4 if(number==1) return 1;
5 if(number==2) return 2;
6 return jumpFloor(number-1)+jumpFloor(number-2);
7 }
8 };
C++
1 public class Solution {
2 public int JumpFloor(int number) {
3 if(number==1) return 1;
4 if(number==2) return 2;
5 return JumpFloor(number-1)+JumpFloor(number-2);
6 }
7 }
Java
第九题:变态跳台阶
题目描述
一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
题解:
和斐波那契数列推导一样,这个推一下吧。
用Fib(n)表示青蛙跳上n阶台阶的跳法数,青蛙一次性跳上n阶台阶的跳法数1(n阶跳),设定Fib(0) = 1;
当n = 1 时,只有一种跳法,即1阶跳:Fib(1) = 1;
当n = 2 时,有两种跳的方式,一阶跳和二阶跳:Fib(2) = Fib(1) + Fib(0) = 2;
当n = 3 时,有三种跳的方式,第一次跳出一阶后,后面还有Fib(3-1)中跳法;第一次跳出二阶后,后面还有Fib(3-2)中跳法;第一次跳出三阶后,后面还有Fib(3-3)中跳法
当n = n 时,共有n种跳的方式,第一次跳出一阶后,后面还有Fib(n-1)中跳法;第一次跳出二阶后,后面还有Fib(n-2)中跳法…第一次跳出n阶后,后面还有 Fib(n-n)中跳法.
Fib(n) = Fib(n-1)+Fib(n-2)+Fib(n-3)+……….+Fib(n-n)=Fib(0)+Fib(1)+Fib(2)+…….+Fib(n-1)
又因为Fib(n-1)=Fib(0)+Fib(1)+Fib(2)+…….+Fib(n-2)
两式相减得:Fib(n) = 2*Fib(n-1) n >= 2
参考代码:
1 class Solution {
2 public:
3 int jumpFloorII(int number) {
4 if(number==0) return 0;
5 int ans=1;
6 for(int i=1;i<number;++i)
7 ans=ans*2;
8 return ans;
9 }
10 };
C++
1 public class Solution {
2 public int JumpFloorII(int number) {
3 if(number==0) return 0;
4 int ans=1;
5 for(int i=1;i<number;++i)
6 ans=ans*2;
7 return ans;
8 }
9 }
Java
第十题:矩形覆盖
题目描述
我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?
题解:
n=1
:只有横放一个矩形一种解决办法n=2
:有横放一个矩形,竖放两个矩形两种解决办法n=3
:n=2
的基础上加1个横向,n=1的基础上加2个竖向n=4
:n=3
的基础上加1个横向,n=2的基础上加2个竖向
...
n=n
:n = f(n-1) + f(n-2)
参考代码:
1 class Solution {
2 public:
3 int rectCover(int n) {
4 if(n==0) return 0;
5 if(n==1) return 1;
6 if(n==2) return 2;
7 int a=2,b=1,c;
8 for(int i=3;i<=n;++i)
9 {
10 c=a;
11 a=a+b;
12 b=c;
13 }
14 return a;
15 }
16 };
C++
1 public class Solution {
2 public int RectCover(int n) {
3 if(n==0) return 0;
4 if(n==1) return 1;
5 if(n==2) return 2;
6 int a=2,b=1,c;
7 for(int i=3;i<=n;++i)
8 {
9 c=a;
10 a=a+b;
11 b=c;
12 }
13 return a;
14 }
15 }
Java
第十一题:二进制中一的个数
题目描述
输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
题解:
每次n&(n-1)即可以把最后一个一取出来;
参考代码:
1 class Solution {
2 public:
3 int NumberOf1(int n) {
4 int ans=0;
5 while(n)
6 {
7 n&=(n-1);
8 ans++;
9 }
10 return ans;
11 }
12 };
C++
1 public class Solution {
2 public int NumberOf1(int n) {
3 int ans=0;
4 while(n!=0)
5 {
6 n&=(n-1);
7 ans++;
8 }
9 return ans;
10 }
11 }
Java
第十二题:数值的整数次方
题目描述
给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。
保证base和exponent不同时为0
题解:
注意正负号,快速幂即可;
参考代码:
1 class Solution {
2 public:
3 double Power(double b, int e) {
4 if(e==0) return 1;
5 if(e==1) return b;
6 double res=1;
7 int tmp=0;
8 if(e<0) e=-e,tmp=1;
9
10 while(e!=0)
11 {
12 if(e&1) res=res*b;
13 b=b*b;
14 e>>=1;
15 }
16 if(tmp==1) res=1.0/res;
17
18 return res;
19 }
20 };
C++
1 public class Solution {
2 public double Power(double b, int ee) {
3 if(ee==0) return 1;
4 if(ee==1) return b;
5 double res=1;
6 int tmp=0;
7 if(ee<0)
8 {
9 ee=-ee;
10 tmp=1;
11 }
12
13 while(ee!=0)
14 {
15 if((ee&1)==1) res=res*b;
16 b=b*b;
17 ee>>=1;
18 }
19 if(tmp==1) res=1.0/res;
20
21 return res;
22 }
23 }
Java
第十三题:调整该数组中数字的顺序
题目描述
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
题解:
我们用 i记录奇数的位置,j表示偶数的左边界,每次遇到一个奇数,就把j~i-1的偶数向后移一位,然后把这个奇数放到第j个位置上,j++;
参考代码:
1 class Solution {
2 public:
3 void reOrderArray(vector<int> &array) {
4 vector<int> t1,t2;
5 int i,j;
6 for(i=0;i<array.size();i++){
7 if(array[i]%2!=0){
8 t1.push_back(array[i]);
9 }else{
10 t2.push_back(array[i]);
11 }
12 }
13 for(i=0;i<t1.size();i++){
14 array[i]=t1[i];
15 }
16 for(j=0;j<t2.size()&&i<array.size();j++,i++){
17 array[i]=t2[j];
18 }
19 }
20 };
C++
1 public class Solution {
2 public void reOrderArray(int[] array) {
3 int j = 0;
4 for (int i = 0; i < array.length; i++) {
5 if (array[i] % 2 == 1) {
6 //如果是奇数的话
7 if (i != j) {
8 int temp = array[i];
9 int k = i;
10 for (k = i; k > j; k--) {
11 array[k] = array[k - 1];
12 }
13 array[k] = temp;
14
15 }
16 j++;
17 }
18 }
19 }
20 }
Java
第十四题:输出链表中倒数第k个结点
题目描述
输入一个链表,输出该链表中倒数第k个结点。
题解:
用快慢指针法,快指针先走k-1步,然后快慢指针一起移动即可。
参考代码:
1 /*
2 struct ListNode {
3 int val;
4 struct ListNode *next;
5 ListNode(int x) :
6 val(x), next(NULL) {
7 }
8 };*/
9 class Solution {
10 public:
11 ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
12 ListNode* p=pListHead;
13 ListNode* q=pListHead;
14 int i=0;
15 for(;p!=NULL;i++)
16 {
17 if(i>=k)
18 q=q->next;
19 p=p->next;
20 }
21 if(i<k)
22 return NULL;
23 else
24 return q;
25 }
26 };
C++
1 /*
2 public class ListNode {
3 int val;
4 ListNode next = null;
5
6 ListNode(int val) {
7 this.val = val;
8 }
9 }*/
10 public class Solution {
11 public ListNode FindKthToTail(ListNode pListHead,int k) {
12 ListNode p=pListHead;
13 ListNode q=pListHead;
14 int i=0;
15 for(;p!=null;i++)
16 {
17 if(i>=k)
18 q=q.next;
19 p=p.next;
20 }
21 if(i<k)
22 return null;
23 else
24 return q;
25 }
26 }
Java
第十五题:反转链表
题目描述
输入一个链表,反转链表后,输出新链表的表头。
题解:
记录3个指针,pre,now,next
pre:表示now的前一个节点,now:表示当前节点,next:表示now的下一个节点(可能为NULL);
每次让
next=now->next;
now->next=pre;
pre=now;
now=next;
结束标志为 now==NULL;
最后输出指针now就行了。
参考代码:
1 /*
2 struct ListNode {
3 int val;
4 struct ListNode *next;
5 ListNode(int x) :
6 val(x), next(NULL) {
7 }
8 };*/
9 class Solution {
10 public:
11 ListNode* ReverseList(ListNode* pHead) {
12 ListNode *reverse=NULL;
13 ListNode *node=pHead;
14 ListNode *pre=NULL;
15 while(node!=NULL)
16 {
17 ListNode *next=node->next;
18 if(next==NULL)
19 reverse=node;
20 node->next=pre;
21 pre=node;
22 node=next;
23 }
24 return reverse;
25 }
26 };
C++
1 public class Solution {
2 public ListNode ReverseList(ListNode head) {
3 ListNode pre = null;
4 ListNode now = head;
5 ListNode aft = null;
6 while(now != null){
7 aft = now.next;
8 now.next=pre;
9 pre = now;
10 now = aft;
11 }
12 return pre;
13 }
14 }
Java
第十六题 反转链表
时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M 热度指数:662243
本题知识点: 链表
题目描述
输入一个链表,反转链表后,输出新链表的表头。
题解:
记录3个指针即可。
参考代码:
public class Solution {
public ListNode ReverseList(ListNode head) {
ListNode pre = null;
ListNode now = head;
ListNode aft = null;
while(now != null){
aft = now.next;
now.next=pre;
pre = now;
now = aft;
}
return pre;
}
}
Java
第十七题 合并两个有序链表
时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M 热度指数:641239
本题知识点: 链表
题目描述
输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
题解:
新建一个链表头。然后依次将两个链表中的元素加入即可,判断一下大小。
参考代码:
public class Solution {
public ListNode Merge(ListNode l1,ListNode l2) {
ListNode l3=new ListNode(0);
ListNode l4=l3;
while(l1!=null && l2!=null)
{
if(l1.val<=l2.val)
{
l3.next=l1;
l1=l1.next;
}
else
{
l3.next=l2;
l2=l2.next;
}
l3=l3.next;
}
if(l1!=null) l3.next=l1;
else if(l2!=null) l3.next=l2;
return l4.next;
}
}
Java
第十八题 树的子结构
时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M 热度指数:617491
本题知识点: 二叉树
题目描述
输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)
题解:
对于树B,要么和root本身相同,要么和root.left相同,要么和root.right相同。否则就不是树A的子结构。
递归判断即可。
参考代码:
/**
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public boolean IsSubtree(TreeNode a,TreeNode b)
{
if(b==null) return true;
if(a==null) return false;
if(a.val==b.val)
{
return IsSubtree(a.left,b.left) && IsSubtree(a.right,b.right);
}
else return false;
}
public boolean HasSubtree(TreeNode root1,TreeNode root2)
{
if(root2==null||root1==null) return false;
return IsSubtree(root1,root2)||HasSubtree(root1.left,root2)||HasSubtree(root1.right,root2);
}
}
Java
第十九题 二叉树镜像
时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M 热度指数:355640
本题知识点: 树
题目描述
操作给定的二叉树,将其变换为源二叉树的镜像。
输入描述:
二叉树的镜像定义:源二叉树
8
/ \
6 10
/ \ / \
5 7 9 11
镜像二叉树
8
/ \
10 6
/ \ / \
11 9 7 5
题解:
水题,递归将左右子树交换即可。
参考代码:
/**
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public void Mirror(TreeNode root)
{
if(root==null) return ;
TreeNode temp=root.left;
root.left=root.right;
root.right=temp;
Mirror(root.left);
Mirror(root.right);
}
}
Java
第二十题 顺时针打印矩阵
时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M 热度指数:652806
本题知识点: 数组
题目描述
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.
题解:
记录左右上下边界,然后依次输出(注意判断是否重合,左右,上下)。
参考代码:
class Solution {
public:
vector<int> printMatrix(vector<vector<int> > matrix)
{
int row = matrix.size();
if(row==0) return {};
int col = matrix[0].size();
vector<int> res;
if (row == 0 || col == 0) return res;
// 定义四个关键变量,表示左上和右下的打印范围
int left = 0, top = 0, right = col - 1, bottom = row - 1;
while (left <= right && top <= bottom)
{
// left to right
for (int i = left; i <= right; ++i) res.push_back(matrix[top][i]);
// top to bottom
for (int i = top + 1; i <= bottom; ++i) res.push_back(matrix[i][right]);
// right to left
if (top != bottom)
for (int i = right - 1; i >= left; --i) res.push_back(matrix[bottom][i]);
// bottom to top
if (left != right)
for (int i = bottom - 1; i > top; --i) res.push_back(matrix[i][left]);
left++,top++,right--,bottom--;
}
return res;
}
};
C++
第二十一题 包含min函数的栈
时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M 热度指数:381435
本题知识点: 栈
题目描述
定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1))。
题解:使用两个栈st,st2.st里面放元素,st2是个单调栈,保存当前栈st中的最小元素。
参考代码:
class Solution {
public:
stack<int> st,st2;
void push(int value)
{
st.push(value);
if(st2.empty() || (value<st2.top()))
st2.push(value);
}
void pop()
{
if(!st.empty())
{
int val=st.top();
st.pop();
if(val==st2.top())
st2.pop();
}
}
int top()
{
if(!st.empty())
return st.top();
}
int min()
{
if(!st2.empty())
return st2.top();
}
};
C++
第二十二题 栈的压入和弹出
题目描述
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列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)
{
stack<int> st;
int id=0;
for(int i=0;i<popV.size();++i)
{
while(st.empty()||st.top()!=popV[i])
{
st.push(pushV[id++]);
if(id>pushV.size())
return false;
}
st.pop();
}
if(st.empty()) return true;
else return false;
}
};
C++
第二十三题 从上往下打印二叉树
题目描述
从上往下打印出二叉树的每个节点,同层节点从左至右打印。
题解:用队列即可。
参考代码:
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
class Solution {
public:
vector<int> PrintFromTopToBottom(TreeNode* root)
{
vector<int> ans;
if(root==NULL) return ans;
queue<TreeNode*> q;
q.push(root);
int cnt=1;
while(!q.empty())
{
TreeNode* u=q.front();q.pop();
ans.push_back(u->val);
if(u->left) q.push(u->left);
if(u->right) q.push(u->right);
}
return ans;
}
};
C++
第二十四题 二叉搜索树的后序遍历序列
题目描述
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。
题解:二叉搜索树的性质:左子树的元素都比根小,右子树的元素都比根大。这样,知道最后一个元素一定是根,然后我们对每一层找到第一个比根大的元素,然后判断后面的是否都比根大,如果有比根小的,则返回false,否则继续判断左右子树,返回true,递归判断。
参考代码:
class Solution {
public:
bool VerifySquenceOfBST(vector<int> sequence) {
return bst(sequence,0,sequence.size()-1);
}
bool bst(vector<int> sequence,int begin,int end)
{
if(sequence.empty()||begin>end)
return false;
int root=sequence[end];
int i=begin;
for(;i<end;++i)
if(sequence[i]>root) break;
for(int j=i;j<end;++j)
if(sequence[j]<root) return false;
bool left=true;
if(i>begin)
left=bst(sequence,begin,i-1);
bool right=true;
if(i<end-1)
right=bst(sequence,i,end-1);
return left&&right;
}
};
C++
未完待续~