1.找出数组中重复的数字
注意点:
- 1.有一个出现在0~n-1之外的就要返回-1
- 2.空值返回-1
- 3.时间复杂度O(n),空间复杂度O(1)的解法
class Solution {
public:
int duplicateInArray(vector& nums) {
int n=nums.size();
if(n==0) return -1;
for(int i=0;i=n) return -1;
}
for(int i=0;i
2.不修改数组找出重复的数字
分治+抽屉原理,将每个数的取值的区间[1, n]划分成[1, n/2]和[n/2+1, n]两个子区间,然后分别统计两个区间中数的个数。
class Solution {
public:
int duplicateInArray(vector& nums) {
int l=1,r=nums.size()-1;//n+1长度的数组
while(l>1;//[l,mid],[mid+1,r]
int s=0;
for(auto x:nums) s+=x>=l&&x<=mid;
if(s>mid-l+1) r=mid;
else
l=mid+1;
}
return l;
}
};
3.二维数组中的查找
每一步会排除一行或者一列,矩阵一共有 n 行,m 列,所以最多会进行 n+m 步。所以时间复杂度是 O(n+m)。
class Solution {
public:
bool searchArray(vector> array, int target) {
if(array.empty())return false;
int i=0,j=array[0].size()-1;
while(i=0)
{
if(array[i][j]==target) return true;
if(array[i][j]>target) j--;
else i++;
}
return false;
}
};
4.替换空格
class Solution {
public:
string replaceSpaces(string &str) {
string res;
for(auto x:str)
{
if(x==' ')
res+="%20";
else
res+=x;
}
return res;
}
};
5.从尾到头打印链表
反向迭代器涨姿势了,vector
class Solution {
public:
vector printListReversingly(ListNode* head) {
vectorres;
while(head)
{
res.push_back(head->val);
head=head->next;
}
return vector(res.rbegin(),res.rend());
}
};
6.重建二叉树
class Solution {
public:
unordered_mapmp;
TreeNode* buildTree(vector& preorder, vector& inorder) {
int n=preorder.size();
for(int i=0;i& pre,vector& in,int pl,int pr,int il,int ir)
{
if(il>ir) return NULL;
int k=mp[pre[pl]]-il;//中序遍历中左子树的数量
//重构根节点
TreeNode* root=new TreeNode(pre[pl]);
//递归左子树
root->left=dfs(pre,in,pl+1,pl+k,il,il+k-1);
//递归右子树
root->right=dfs(pre,in,pl+k+1,pr,il+k+1,ir);
return root;
}
};
7.二叉树的下一个节点
俗称树的后继,给定一棵二叉树的其中一个节点,请找出中序遍历序列的下一个节点。
-
- 如果有右子树,那么右子树最左侧结点就是答案
-
- 如果没有右子树,那么就一直往上找,直到找到当前这个点,它是它father的左子树,那么它的father就是后继
class Solution {
public:
TreeNode* inorderSuccessor(TreeNode* p) {
if(p->right)
{
p=p->right;
while(p->left)
p=p->left;
return p;
}
while(p->father&&p==p->father->right) p=p->father;
return p->father;
}
};
8.用两个栈实现队列
两个栈stk与cache,一个用于存,另一个用于取或者查
class MyQueue {
public:
stackstk,cache;
/** Initialize your data structure here. */
MyQueue() {
}
/** Push element x to the back of queue. */
void push(int x) {
stk.push(x);
}
void copy(stack&a,stack&b)
{
while(a.size())
{
b.push(a.top());
a.pop();
}
}
/** Removes the element from in front of queue and returns that element. */
int pop() {
copy(stk,cache);
int res=cache.top();
cache.pop();
copy(cache,stk);
return res;
}
/** Get the front element. */
int peek() {
copy(stk,cache);
int res=cache.top();
copy(cache,stk);
return res;
}
/** Returns whether the queue is empty. */
bool empty() {
return stk.empty();
}
};
9.斐波那契数列
- 面试的时候能不用递归就不用递归
class Solution {
public:
int res=0;
int Fibonacci(int n) {
if(n==0) return 0;
if(n==1||n==2) return 1;
return res=Fibonacci(n-1)+Fibonacci(n-2);
}
};
- 首选dp
class Solution {
public:
int Fibonacci(int n) {
int dp[n+10];
dp[0]=0;
dp[1]=1;
dp[2]=1;
for(int i=3;i<=n;i++)
{
dp[i]=dp[i-1]+dp[i-2];
}
return dp[n];
}
};
10.矩阵中的路径
dfs+回溯,注意边界条件的顺序
class Solution {
public:
int dx[4]={0,1,0,-1};
int dy[4]={1,0,-1,0};
bool hasPath(vector>& matrix, string &str) {
for(int i=0;i>&matrix,string &str,int u,int x,int y)
{
if(matrix[x][y]!=str[u])
return false;
if(u==str.size()-1)
return true;
char t=matrix[x][y];
matrix[x][y]='*';
for(int i=0;i<4;i++)
{
int a=x+dx[i],b=y+dy[i];
if(a>=0&&a=0&&b