第一题:二维数组的查找
题目描述
题解:
参考代码:

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 };
第二题:替换空格
题目描述
题解:
参考代码:


1 public class Solution { 2 public String replaceSpace(StringBuffer str) { 3 return str.toString().replaceAll("\s", "%20"); 4 } 5 }
第三题:从尾到头打印字符
题目描述
题解:
每次插入到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 };
第四题:重建二叉树
题目描述
题解:
参考代码:

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 };

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 }
第五题:用两个栈来实现一个队列
题目描述
题解:
参考代码:

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 };

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 }
第六题:旋转数组最小的数字
题目描述
输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。
例如数组{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 };

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 }
第七题:斐波那契数列
题目描述
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 };

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 }
第八题:跳台阶
题目描述
题解:
参考代码:

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 };

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 }
第九题:变态跳台阶
题目描述
题解:
和斐波那契数列推导一样,这个推一下吧。
用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 };

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 }
第十题:矩形覆盖
题目描述
题解:
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 };

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 }
第十一题:二进制中一的个数
题目描述
题解:
参考代码:

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 };

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 }
第十二题:数值的整数次方
题目描述
题解:
注意正负号,快速幂即可;
参考代码:

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 };

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 }
第十三题:调整该数组中数字的顺序
题目描述
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
题解:
我们用 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 };

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 }
第十四题:输出链表中倒数第k个结点
题目描述
输入一个链表,输出该链表中倒数第k个结点。
题解:
参考代码:

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 };

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 }
第十五题:反转链表
题目描述
题解:
参考代码:

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 };

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 }
第十六题 反转链表
题目描述
题解:
记录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; } }
第十七题 合并两个有序链表
题目描述

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; } }
第十八题 树的子结构
题目描述

/** 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); } }
第十九题 二叉树镜像
题目描述
输入描述:
二叉树的镜像定义:源二叉树 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); } }
第二十题 顺时针打印矩阵
题目描述

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; } };
第二十一题 包含min函数的栈
题目描述

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(); } };
第二十二题 栈的压入和弹出
题目描述
题解:我们模拟栈的压入,如果当前栈顶元素等于出栈的最前面的元素,则出栈,后移出栈数组的最前面元素,知道不相等,或则入栈数组元素用完。左后判断栈是否为空即可。
参考代码:

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; } };
第二十三题 从上往下打印二叉树
题目描述

/* 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; } };
第二十四题 二叉搜索树的后序遍历序列
题目描述

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; } };