61序列化二叉树
请实现两个函数,分别用来序列化和反序列化二叉树
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};
*/
class Solution {
public:
vector<int> buf;
void dfs1(TreeNode *root){
if(!root)
buf.push_back(0xFFFFFFFF);
else{
buf.push_back(root->val);
dfs1(root->left);
dfs1(root->right);
}
}
TreeNode* dfs2(int* &str){
if(*str == 0xFFFFFFFF){
++str;
return NULL;
}
TreeNode* res = new TreeNode(*str);
str++;
res->left = dfs2(str);
res->right = dfs2(str);
return res;
}
char* Serialize(TreeNode *root) {
buf.clear();
dfs1(root);
int bufSize = buf.size();
int *res = new int[bufSize];
for(int i = 0;i < bufSize; i++) res[i] = buf[i];
return (char*)res;
}
TreeNode* Deserialize(char *str) {
int *p = (int*)str;
return dfs2(p);
}
};
62二叉搜索树的第k个结点
题目描述
给定一棵二叉搜索树,请找出其中的第k小的结点。例如, (5,3,7,2,4,6,8) 中,按结点数值大小顺序第三小结点的值为4。
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};
*/
class Solution {
public:
TreeNode* ans=NULL;
int dfs(TreeNode* r,int k){
if(r==NULL)return 0;//空就是没有结点
int ln=dfs(r->left,k);//搜左儿得到左子树的结点数
if(ln+1==k)ans=r;//左子树结点数+1是K则当前点就是答案了
int lr=dfs(r->right,k-ln-1);//搜左儿得到右子树的结点数
return ln+lr+1;//返回当前子树结点数
}
TreeNode* KthNode(TreeNode* pRoot, int k)
{
int hhh=dfs(pRoot,k);
return ans;
}
};
63数据流中的中位数
如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。
class Solution {
public:
vector<int> s;
void Insert(int num)
{
if(s.empty()){//空
s.push_back(num);
return ;
}
if(num>s[s.size()-1]){//MAX
s.push_back(num);
return ;
}
s.push_back(s[s.size()-1]);//最大值后移
for(int i=s.size()-2;i>=1;i--){//逐位判
if(num>=s[i]){//大于当前位
s[i+1]=num;//就赋在其右边
return ;
}
s[i]=s[i-1];
}
//比1号位还要小,则要跟0号位比较
if(num<=s[0])s[0]=num;//更小就在左边
else s[1]=num;//否则在右边
}
double GetMedian()
{
int len=s.size();
if(len%2==1)return s[len/2];
else return ((double)s[len/2]+(double)s[len/2-1])/2;
}
};
64滑动窗口的最大值
给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6,6,6,5}; 针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个: {[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,1}, {2,3,4,[2,6,2],5,1}, {2,3,4,2,[6,2,5],1}, {2,3,4,2,6,[2,5,1]}。
class Solution {
public:
multiset<int> s;
vector<int> maxInWindows(const vector<int>& num, unsigned int size)
{
vector<int> ans;
if(num.size()==0 || size==0 || num.size()<size)return ans;
int len=num.size(),mx=num[0];
for(int i=0;i<size;i++){
s.insert(num[i]);
mx=mx>num[i]?mx:num[i];
}
ans.push_back(mx);
int l=0,r=size;
for(int i=size;i<len;i++){
s.erase(num[l++]);
s.insert(num[r++]);
multiset<int>::iterator ip = s.end(); // 返回指向最后一个元素的迭代器
--ip;
ans.push_back(*ip);
}
return ans;
}
};
65矩阵中的路径
请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则之后不能再次进入这个格子。 例如 a b c e s f c s a d e e 这样的3 X 4 矩阵中包含一条字符串"bcced"的路径,但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。
class Solution {
public:
bool helper(char* matrix, int rows, int cols, int i, int j, char* str, int k, int* flag){
int index = i * cols + j;
if(i < 0 || i >= rows || j < 0 || j >= cols || matrix[index] != str[k] || flag[index] == 1){
//下标不符合,index对应的值不为和字符数组中的不一致,或者该index已经被访问,这些情况只要有符合的就返回false
//只有上面的所有情况都不符合,也就是值相等,且没有访问过,下标不符合
return false;
}
if(k == strlen(str) - 1){
return true;
}
flag[index] = 1;
if(helper(matrix, rows, cols, i - 1, j, str, k + 1, flag)
||helper(matrix, rows, cols, i + 1, j, str, k + 1, flag)
||helper(matrix, rows, cols, i, j - 1, str, k + 1, flag)
||helper(matrix, rows, cols, i , j + 1, str, k + 1, flag)){
return true;
}
flag[index] = 0;
return false;
}
bool hasPath(char* matrix, int rows, int cols, char* str)
{
int* flag = new int[strlen(matrix)];
for(int i = 0; i < rows; i ++){
for(int j = 0; j < cols; j ++){
if(helper(matrix, rows, cols, i, j, str, 0, flag)){
return true;
}
}
}
return false;
}
};
66机器人的运动范围
地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子。 例如,当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18。但是,它不能进入方格(35,38),因为3+5+3+8 = 19。请问该机器人能够达到多少个格子?
class Solution {
public:
typedef pair<int,int> p;
int sum(int x){
int ans=0;
while(x>0){
ans+=x%10;
x/=10;
}
return ans;
}
int dx[4]={-1,1,0,0};
int dy[4]={0,0,-1,1};
int movingCount(int threshold, int rows, int cols)
{
int vis[rows][cols];
memset(vis,0,sizeof(vis));
queue< p > qe;
qe.push( p(0,0) );
int ans=0;
while(!qe.empty()){
p tp=qe.front();
qe.pop();
ans++;
for(int i=0;i<4;i++){
int nx=tp.first+dx[i],ny=tp.second+dy[i];
if( vis[nx][ny]==0 && sum(nx)+sum(ny)<=threshold && 0<=nx && nx<=rows && 0<=ny && ny<=cols ){
qe.push(p(nx,ny));
vis[nx][ny]=1;
}
}
}
return ans;
}
};