Day19-学习内容:
1.剑指Offer
面试题55:二叉树的深度
面试题55:判断是否平衡二叉树
面试题56: 数组中数字出现的次数
2.Leetcode
例1:相同直线上的最大点数
例2:二叉树最大路径和
3.2018年腾讯春招技术编程题
例4:小Q的歌单
4.2017年阿里巴巴秋招笔试题
题目描述:输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。
思路:递归
代码:
class Solution {
public:
int TreeDepth(TreeNode* pRoot)
{
if(pRoot==nullptr){
return 0;
}
int left=TreeDepth(pRoot->left);
int right=TreeDepth(pRoot->right);
return left>right?left+1:right+1;
}
};
题目描述:输入一棵二叉树,判断该二叉树是否是平衡二叉树。
思路:递归,为了每个节点只遍历一次,在每次遍历时需用指针记录下它的深度。
代码:
class Solution {
public:
bool IsBalanced_Solution(TreeNode* pRoot) {
if(pRoot==nullptr){
return true;
}
int depth=0;
return IsBalanced(pRoot,&depth);
}
bool IsBalanced(TreeNode* pRoot,int *depth){
if(pRoot==nullptr){
*depth=0;
return true;
}
int left,right;
if(IsBalanced(pRoot->left,&left)&&IsBalanced(pRoot->right,&right)){
int diff=left-right;
if(diff<=1&&diff>=-1){
*depth=1+(left>right?left:right);
return true;
}
}
return false;
}
};
题目描述:一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
思路:使用二进制和异或操作,原理是一个数字异或它本身是等于零的。
代码:
class Solution {
public:
void FindNumsAppearOnce(vector data,int* num1,int *num2) {
if(data.empty()||data.size()<2) return;
int len=data.size();
int resultOR=0;
for(int i=0;i>1;
++index;
}
return index;
}
bool IsBit1(int num, unsigned int index){
num=num>>index;
return (num&1);
}
};
题目描述:Given n points on a 2D plane, find the maximum number of points that lie on the same straight line.
思路:需要两重循环,第一重循环遍历起始点a,第二重循环遍历剩余点b。
a和b如果不重合,就可以确定一条直线。
对于每个点a,构建 斜率->点数 的map。
(1)b与a重合,以a起始的所有直线点数+1 (用dup统一相加)
(2)b与a不重合,a与b确定的直线点数+1
代码:
class Solution {
public:
int maxPoints(vector &points) {
int len=points.size();
if(len==0) return 0;
if(len==1) return 1;
int res=0;
for(int i=0;i map;
int vcnt=0;
int dup=0;
for(int j=0;j
题目描述:
Given a binary tree, find the maximum path sum.
The path may start and end at any node in the tree.
For example:
Given the below binary tree,
1 / \ 2 3
Return6.
思路:一个结点自身的最长路径就是它的左子树返回值(如果大于0的话),
加上右子树的返回值(如果大于0的话),再加上自己的值。
在过程中求得当前最长路径时比较一下是不是目前最长的,如果是则更新,
算法的本质还是一次树的遍历,所以复杂度是O(n),而空间上仍然是栈大小O(logn)。
代码:
class Solution {
public:
int maxPathSum(TreeNode *root) {
if(root==nullptr){
return 0;
}
queue q;
q.push(root);
int max=root->val;
while(!q.empty()){
TreeNode *node=q.front();
q.pop();
int cur=node->val;
int left=maxPathSumCore(node->left);
int right=maxPathSumCore(node->right);
if(left>0){
cur+=left;
}
if(right>0){
cur+=right;
}
if(cur>max){
max=cur;
}
if(node->left){
q.push(node->left);
}
if(node->right){
q.push(node->right);
}
}
return max;
}
int maxPathSumCore(TreeNode *node){
if(node==nullptr){
return 0;
}
int max=node->val;
int left=maxPathSumCore(node->left);
int right=maxPathSumCore(node->right);
int bigger=(left>right?left:right);
if(bigger>0){
max+=bigger;
}
return max;
}
};
题目描述:
小Q有X首长度为A的不同的歌和Y首长度为B的不同的歌,现在小Q想用这些歌组成一个总长度正好为K的歌单,每首歌最多只能在歌单中出现一次,在不考虑歌单内歌曲的先后顺序的情况下,请问有多少种组成歌单的方法。
输入描述:
每个输入包含一个测试用例。 每个测试用例的第一行包含一个整数,表示歌单的总长度K(1<=K<=1000)。 接下来的一行包含四个正整数,分别表示歌的第一种长度A(A<=10)和数量X(X<=100)以及歌的第二种长度B(B<=10)和数量Y(Y<=100)。保证A不等于B。
输出描述:
输出一个整数,表示组成歌单的方法取模。因为答案可能会很大,输出对1000000007取模的结果。
输入例子1:
5 2 3 3 3
输出例子1:
9
代码:
方法1:背包+滚动数组
#include
using namespace std;
const int mod=1000000007;
int a,x,b,y,k;
long long dp[1010];
int p[210];
int main() {
scanf("%d",&k);
scanf("%d%d%d%d",&a,&x,&b,&y);
dp[0]=1;
for(int i=1; i<=x; i++) p[i]=a;
for(int i=x+1; i<=x+y; i++) p[i]=b;
for(int i=1; i<=x+y; i++) {
for(int j=k; j>=p[i]; j--)
dp[j]=(dp[j]%mod+dp[j-p[i]]%mod)%mod;
}
printf("%lld\n",dp[k]%mod);
return 0;
}
#include
#include
#include
using namespace std;
const int mod=1000000007;
int main()
{
int i, j, K, la, lb, na, nb,result;
cin >> K;
cin >> la >> na >> lb >> nb; //输入的信息
int *lens=new int[na+nb+1]; //建立动态数组lens[j]表达第j首歌长度
for(i=1;i<=na;i++){
lens[i]=la;
}
for(i=1;i<=nb;i++){
lens[i+na]=lb;
} //将na,nb数量的歌的长度按顺序存储进数组lens
int **db=new int*[K+1]; //建立二维动态数组db[i][j]存储j首歌组成长度为i的方法
for(int i=0;i=lens[j])
db[i][j]=(db[i][j-1]+db[i-lens[j]][j-1])%mod;
else db[i][j]=db[i][j-1]%mod;
}
}
//当i的长度大于等于第j首歌长度时,用j首歌组成长度为i的方法分两部分,1部分为用j-1首歌组成长度为i的歌单
//另一部分为由j-1首歌组成长度为i-lens[j]的歌单,因为第j首歌长度恰好为lens[j]
cout<
例17:假定某同学使用Naive Bayesian(NB)分类模型时,不小心将训练数据的两个维度搞重复了,那么关于NB的说法中正确的是:(B,D)
A.这个被重复的特征在模型中的决定作用会被加强
B.模型效果相比无重复特征的情况下精确度会降低
C.如果所有特征都被重复一遍,得到的模型预测结果相对于不重复的情况下的模型预测结果一样。
D.当两列特征高度相关时,无法用两列特征相同时所得到的结论来分析问题
E.NB可以用来做最小二乘回归
F.以上说法都不正确
正确答案:B D
解析:D.主要原因就是由于存在重复的类别之后,破坏了原本的独立性假设,NB的核心在于它假设向量的所有分量之间是独立的。
B.对于特征独立型的模型,当存在高度相关特征的时候,由于冗余特征并没有增加数据的信息,但是它却对模型分类的 置信度产生了影响,冗余特征产生的效果也会叠加在模型中,从而使得模型效果变差。
例18:以下哪个行为,不会明显加剧客户端运行过程中的卡顿:(C)
A.在主线程集中处理耗时的操作
B.在子线程集中处理耗时的操作
C.在其它进程集中处理耗时的操作
D.提高后台线程的优先级
E.降低主线程的优先级
F.页面存在多个重叠显示的控件
正确答案:C
解析:在其他进程里面处理耗时操作,相当于在另外的虚拟机里面执行操作,因此和当前的虚拟机也就是客户端没有明显的关系,可以类比一下AIDL,客户端的一次请求就相当于一次RPC,请求到了服务器之后会在Binder线程池执行操作,而如果后台软件过多,只是因为CPU轮换和内存不足。题目说的是不会明显加剧卡顿,这是会造成卡顿的。
例19:以下程序的输出是:(D)
A.1,6 B.2,5 C.2,4 D.3,5 E.4,7 F.1,1
解析:首先 斐波那契数列 f(n)= f(n-1) +f(n-2)
可知 f(0)=1 f(1)=1 f(2) = f(1) + f(0) = 2 f(3)=f(2)+f(1)=3 以此类推 f(4) = 5 ,
f(5) = 8 , f(6) = 13 , f(7) = 21 , f(8) = 34 f(9) = 55.
f(7) = 21 , f(9) = 55.
count函数,作用是求该数字的二进制中1的个数,可参考参考 MIT HAKM 详细算法:
https://blog.csdn.net/msquare/article/details/4536388
21的二进制表示10101
55的二进制表示110111
例20.主观题
题目描述:学校图书馆共有 300 万册图书,想统计其中 Computer , Science ,计算机,科学这几个词出现的次数,并按照自然年度分类,如 2016 年出版的书籍中这几个词各自出现的次数, 2015 年······依次类推。
解析:
1.首先将不同年份的书分别记录在不同的文件中, 比如 2016.txt , 2015.txt
2.对每一年的图书记录进行遍历, 解析 HashMap
代码:
HashMap map=new hashMap<>();
map.put("Computer",0);
map.put("Science",0);
map.put("计算机",0);
map.put("科学",0);
public HashMap calculateTimes(HashMap map, string bookName){
if(bookName.length()<=0) return map;
if(bookName.contains("Computer")){
map.put("Computer",map.get("Computer")++);
}
else if(bookName.contains("Science")){
map.put("Science",map.get("Science")++);
}
else if(bookName.contains("计算机")){
map.put("计算机",map.get("计算机")++);
}
else if(bookName.contains("科学")){
map.put("科学",map.get(""科学)++);
}
return map;
}