系列一:1~10题
目录
1、二维数组中的查找【数组】
题目:原题链接
题目描述
在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
1.1、分析
对于这样的数组,我们可以发现,从右上角数字开始比较,若比目标数字小,那么一定不会在第一行,所有可以跳过第一行,若比目标数字大,那么肯定不在最后一列,则可以跳过最后一列。依次这样比较下去,直到相等为止。
1.2、代码
class Solution {
public:
bool Find(int target, vector<vector<int> > array) {
if(array.empty()||array[0].empty()) return false;
int i=0,j=array[0].size()-1;
while(i<array.size()&&j>=0){
if(array[i][j]==target) return true;
else if(array[i][j]>target) j--;
else i++;
}
return false;
}
};
2、替换空格【字符串】
题目:原题链接
题目描述
请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。
2.1、分析
我们可以先定义一个string类型的字符串,由于string类型可以直接用+进行字符串拼接,所以当遇到空格时,我们就加上"%20",不是空格就直接加上原先的字符,最终需要把string类型字符串copy到原字符型数组中。
2.2、代码
class Solution {
public:
void replaceSpace(char *str,int length) {
string res;
for(int i=0;i<length;i++){
if(str[i]==' ') res+="%20";
else res+=str[i];
}
strcpy(str,res.c_str());
}
};
3、从尾到头打印链表【链表】
题目:原题链接
题目描述
输入一个链表,按链表从尾到头的顺序返回一个ArrayList。
3.1、分析
我们可以先按照链表的顺序,把值存在一个容器中,然后使用reverse对容器做一个反转,就可以实现顺序是逆向的了。
3.2、代码
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* ListNode(int x) :
* val(x), next(NULL) {
* }
* };
*/
class Solution {
public:
vector<int> printListFromTailToHead(ListNode* head) {
vector<int> ans;
if(!head) return ans;
for(auto p=head;p;p=p->next){
ans.push_back(p->val);
}
reverse(ans.begin(),ans.end());
return ans;
}
};
4、重建二叉树【树】
题目:原题链接
题目描述
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
4.1、分析
4.2、代码
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int n,m;
unordered_map<int,int> hash; //用于快速根据根节点值,找到在中序遍历的位置
TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
n=pre.size()-1,m=vin.size()-1;
for(int i=0;i<=m;i++) hash[vin[i]]=i;
return dfs(pre,vin,0,n,0,m);
}
TreeNode* dfs(vector<int> &pre,vector<int> &vin,int ps,int pe,int vs,int ve)
{
if(ps>pe) return NULL;
int root_val=pre[ps];
auto root=new TreeNode(root_val);
int k=hash[root_val];
int len=k-vs;
root->left=dfs(pre,vin,ps+1,ps+len,vs,k-1);
root->right=dfs(pre,vin,ps+len+1,pe,k+1,ve);
return root;
}
};
5、用两个栈实现队列【队列】【栈】
题目:原题链接
题目描述
用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。
6.1、分析
其实就是每次压栈时就只往其中一个栈中压入,当需要出队时,如果另一个栈是空的,我们就把数据全部弹到另一个栈中,然后取另一个栈的栈顶元素即可,若另一个栈不是空的,那么直接弹出栈顶元素即可。
6.2、代码
class Solution
{
public:
void push(int node) {
stack1.push(node);
}
int pop() {
if(stack2.size()){ //当stack2不是空的,直接弹出栈顶元素
int k=stack2.top();
stack2.pop();
return k;
}
else{ //若是空的,则把stack1清空,全部弹到stack2中
while(stack1.size()){
int k=stack1.top();
stack1.pop();
stack2.push(k);
}
int t=stack2.top(); //再取栈顶元素
stack2.pop();
return t;
}
}
private:
stack<int> stack1;
stack<int> stack2;
};
7、旋转数组的最小数字【查找】【二分】
题目:原题链接
题目描述
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。
例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。
NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
7.1 分析
7.2 代码
class Solution {
public:
int minNumberInRotateArray(vector<int> num) {
if(num.empty()) return 0;
int l=0,r=num.size()-1;
while(l<r){
int mid=l+r>>1;
if(num[mid]<=num.back()) r=mid;
else l=mid+1;
}
return num[r];
}
};
8、斐波那契数列【动态规划】
题目:原题链接
题目描述
大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0)。
n<=39
8.1、分析
大家应该都知道斐波那契数列,就是当前项等于前两项的和,所以我们只需要定义出第0项和第1项,然后一步步递推过去即可。
8.2、代码
class Solution {
public:
int Fibonacci(int n) {
int first=0,second=1,third=0;
if(n<=1) return n;
for(int i=2;i<=n;i++){
third=first+second;
first=second;
second=third;
}
return third;
}
};
9、跳台阶【动态规划】
题目:原题链接
题目描述
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。
9.1、分析
这题其实是一个特别简单的动态规划问题,我们直接考虑最后一步,最后一步到n阶台阶,可以是一步上来的,也可以是两步上来的,那么总的种数就是从一步上来的种数加上从两步上来的种数,现在子问题就变成了怎样上到n-1阶台阶和n-2阶台阶了。定义状态f[i]表示上到台阶i的种数,状态计算:f[i]=f[i-1]+f[i-2],初始状态就是f[1]=1,f[2]=2,然后依次递推下去。
9.2、代码
class Solution {
public:
int jumpFloor(int number) {
vector<int> f(number+1);
f[1]=1;
f[2]=2;
for(int i=3;i<=number;i++){
f[i]=f[i-1]+f[i-2];
}
return f[number];
}
};
10、变态跳台阶【动态规划】【完全背包问题】
题目:原题链接
题目描述
一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
10.1、分析
同样地,分析最后一步,最后一步可能是一次从n-1台阶跳过来,也可能是从n-2台阶跳过来。。。所以f[n]=f[n-1]+f[n-2]+...+f[1]然后我们发现f[n-1]=f[n-2]+f[n-3]+...+f[1],所以f[n]=2*f[n-1],初始状态f[1]=1。
10.2、代码
class Solution {
public:
int jumpFloorII(int n) {
//f[n]=2*f[n-1];
vector<int> f(n+1);
f[1]=1;
for(int i=2;i<=n;i++)
f[i]=2*f[i-1];
return f[n];
}
};
来源:CSDN
作者:烊萌
链接:https://blog.csdn.net/qq_36417014/article/details/103531220