目录
1.剑指Offer
面试题26:树的子结构
题目描述:
输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)
思路:递归遍历,注意边界值判断。
代码:
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
class Solution {
public:
bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2)
{
bool result=false;
if(pRoot1!=nullptr&&pRoot2!=nullptr){
if(pRoot1->val==pRoot2->val){
result=DoesTree1HaveTree2(pRoot1,pRoot2);
}
if(!result){
result=HasSubtree(pRoot1->left,pRoot2);
}
if(!result){
result=HasSubtree(pRoot1->right,pRoot2);
}
}
return result;
}
bool DoesTree1HaveTree2(TreeNode* pRoot1, TreeNode* pRoot2){
if(pRoot2==nullptr){
return true;
}
if(pRoot1==nullptr){
return false;
}
if(pRoot1->val!=pRoot2->val){
return false;
}
return DoesTree1HaveTree2(pRoot1->left,pRoot2->left)&&DoesTree1HaveTree2(pRoot1->right,pRoot2->right);
}
};
面试题19:正则表达式匹配
题目描述:
请实现一个函数用来匹配包括'.'和'*'的正则表达式。模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但是与"aa.a"和"ab*a"均不匹配
代码:
class Solution {
public:
bool match(char* str, char* pattern)
{
if(str==nullptr||pattern==nullptr){
return false;
}
return matchCore(str,pattern);
}
bool matchCore(char* str, char* pattern){
if(*str=='\0'&&*pattern=='\0'){
return true;
}
if(*str!='\0'&&*pattern=='\0'){
return false;
}
if(*(pattern+1)=='*'){
if(*str==*pattern||(*pattern=='.'&&*str!='\0')){
return matchCore(str+1,pattern+2)||matchCore(str+1,pattern)||matchCore(str,pattern+2);
}
else{
return matchCore(str,pattern+2);
}
}
if(*str==*pattern||(*pattern=='.'&&*str!='\0')){
return matchCore(str+1,pattern+1);
}
return false;
}
};
2.Leetcode
例1:转换排序数组为平衡二叉树
题目描述:
Given an array where elements are sorted in ascending order, convert it to a height balanced BST.
代码:
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode *sortedArrayToBST(vector<int> &num) {
return ArrayToBST(num,0,num.size());
}
TreeNode *ArrayToBST(vector<int> &num, int begin, int end){
if(begin>=end){
return nullptr;
}
int middle=(begin+end)>>1;
TreeNode *root=new TreeNode(num[middle]);
root->left=ArrayToBST(num,begin,middle);
root->right=ArrayToBST(num,middle+1,end);
return root;
}
};
例2:二叉树的最大深度
例1:题目描述:
Given a binary tree, find its maximum depth.
The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node.
思路:递归实现
代码:
/**
* 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 maxDepth(TreeNode *root) {
if(root==nullptr) return 0;
return max(maxDepth(root->left),maxDepth(root->right))+1;
}
};
例3:二叉树的中序遍历
题目描述:
Given a binary tree, return the inorder traversal of its nodes' values.
For example:
Given binary tree{1,#,2,3},
1
\
2
/
3
return[1,3,2].
Note: Recursive solution is trivial, could you do it iteratively?
confused what"{1,#,2,3}"means? > read more on how binary tree is serialized on OJ.
OJ's Binary Tree Serialization:
The serialization of a binary tree follows a level order traversal, where '#' signifies a path terminator where no node exists below.
Here's an example:
1
/ \
2 3
/
4
\
5
The above binary tree is serialized as"{1,2,3,#,#,4,#,#,5}".
思路:递归实现
代码:
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int> inorderTraversal(TreeNode *root) {
vector<int> res;
if(root==nullptr){
return res;
}
return inorderTraversalCore(root,res);
}
vector<int> inorderTraversalCore(TreeNode *root,vector<int> &res){
if(root==nullptr){
return res;
}
if(root->left!=nullptr){
inorderTraversalCore(root->left,res);
}
res.push_back(root->val);
if(root->right!=nullptr){
inorderTraversalCore(root->right,res);
}
return res;
}
};
3.机器学习专项训练
例1:如下表是用户是否使用某产品的调查结果(C)
UID | 年龄 | 地区 | 学历 | 收入 | 用户是否使用调查产品 |
1 | 低 | 北方 | 博士 | 低 | 是 |
2 | 高 | 北方 | 本科 | 中 | 否 |
3 | 低 | 南方 | 本科 | 高 | 否 |
4 | 高 | 北方 | 研究生 | 中 | 是 |
请计算年龄,地区,学历,收入中对用户是否使用调查产品信息增益最大的属性(Log23≈0.63) 正确答案: C 你的答案: C (正确)
A.年龄 B.地区 C.学历 D.收入
解析:所有本科学历都不使用调查产品,所有非本科学历都使用了调查产品。这种可以确定的划分导致信息熵为0,信息增益最大。
例2:关于 logit 回归和 SVM 不正确的是(A)正确答案: A 你的答案: A (正确)
A.Logit回归目标函数是最小化后验概率 B.Logit回归可以用于预测事件发生概率的大小
C.SVM目标是结构风险最小化. D.SVM可以有效避免模型过拟合
解析:A. Logit回归本质上是一种根据样本对权值进行极大似然估计的方法,而后验概率正比于先验概率和似然函数的乘积。logit仅仅是最大化似然函数,并没有最大化后验概率,更谈不上最小化后验概率。A错误 B. Logit回归的输出就是样本属于正类别的几率,可以计算出概率,正确 C. SVM的目标是找到使得训练数据尽可能分开且分类间隔最大的超平面,应该属于结构风险最小化,严格来说也是错误的。 D. SVM可以通过正则化系数控制模型的复杂度,避免过拟合。
例3:机器学习中做特征选择时,可能用到的方法有? (ABCD)正确答案: A B C D 你的答案: B D (错误)
A.卡方 B.信息增益 C.平均互信息 D.期望交叉熵
解析:特征提取算法
特征提取算法分为特征选择和特征抽取两大类
特征选择
常采用特征选择方法。常见的六种特征选择方法:
-
DF(Document Frequency) 文档频率
DF:统计特征词出现的文档数量,用来衡量某个特征词的重要性 -
MI(Mutual Information) 互信息法
互信息法用于衡量特征词与文档类别直接的信息量。
如果某个特征词的频率很低,那么互信息得分就会很大,因此互信息法倾向”低频”的特征词。
相对的词频很高的词,得分就会变低,如果这词携带了很高的信息量,互信息法就会变得低效。 -
(Information Gain) 信息增益法
通过某个特征词的缺失与存在的两种情况下,语料中前后信息的增加,衡量某个特征词的重要性。 -
CHI(Chi-square) 卡方检验法
利用了统计学中的”假设检验”的基本思想:首先假设特征词与类别直接是不相关的
如果利用CHI分布计算出的检验值偏离阈值越大,那么更有信心否定原假设,接受原假设的备则假设:特征词与类别有着很高的关联度。 -
WLLR(Weighted Log Likelihood Ration)加权对数似然
-
WFO(Weighted Frequency and Odds)加权频率和可能性
-
期望交叉熵,以文本分类为例子,期望交叉熵用来度量一个词对于整体的重要程度。
-
特征抽取(降维) PCA等
例4:SPSS中,数据整理的功能主要集中在(AD )等菜单中 正确答案: A D 你的答案: A D (正确)
A.数据 B.直销 C.分析 D.转换
解析:SPSS 对数据整理的功能主要集中在 数据,转换等菜单,分析里面是一堆模型和方法,比如相关分析,回归等。