网易2016实习研发工程师编程题
来源:互联网 发布:阿里云公网宽带 编辑:程序博客网 时间:2024/06/11 02:02
比较重量
小明陪小红去看钻石,他们从一堆钻石中随机抽取两颗并比较她们的重量。这些钻石的重量各不相同。在他们们比较了一段时间后,它们看中了两颗钻石g1和g2。现在请你根据之前比较的信息判断这两颗钻石的哪颗更重。
给定两颗钻石的编号g1,g2,编号从1开始,同时给定关系数组vector,其中元素为一些二元组,第一个元素为一次比较中较重的钻石的编号,第二个元素为较轻的钻石的编号。最后给定之前的比较次数n。请返回这两颗钻石的关系,若g1更重返回1,g2更重返回-1,无法判断返回0。输入数据保证合法,不会有矛盾情况出现。
测试样例:
2,3,[[1,2],[2,4],[1,3],[4,3]],4
返回: 1
按照我自己思路解出:
1、先找出所有大于g1的集合set,所有小于g1的集合set,若可以直接判断,则返回。
2、将所有未与g1、g2直接比较的,归入集合。
3、按照g2查找集合,如果存在大于g2的数在小于g1的集合内,返回1,下面类似。
4、无法比较返回0。
class Cmp {public: int cmp(int g1, int g2, vector<vector<int> > records, int n) { // write code here set<int> bigg1,smallg1; for(int i=0;i<n;++i) { if(records[i][0]==g1) { smallg1.insert(records[i][1]);//小于g1 } else if(records[i][1]==g1) { bigg1.insert(records[i][0]);//大于g1 } //可以直接判断的 if(records[i][0]==g1&&records[i][1]==g2) return 1; if(records[i][0]==g2&&records[i][1]==g1) return -1; } for(int i=0;i<n;++i) { if(records[i][0]!=g1&&records[i][0]!=g2&& records[i][1]!=g1&&records[i][1]!=g2) { if(smallg1.find(records[i][0])!=smallg1.end()) smallg1.insert(records[i][1]); else if(bigg1.find(records[i][1])!=bigg1.end()) bigg1.insert(records[i][0]); } } for(int i=0;i<n;++i) { if(records[i][0]==g2) { if(bigg1.find(records[i][1])!=bigg1.end()) return -1; } if(records[i][1]==g2) { if(smallg1.find(records[i][0])!=smallg1.end()) return 1; } } return 0; }};
二叉树
有一棵二叉树,树上每个点标有权值,权值各不相同,请设计一个算法算出权值最大的叶节点到权值最小的叶节点的距离。二叉树每条边的距离为1,一个节点经过多少条边到达另一个节点为这两个节点之间的距离。
给定二叉树的根节点root,请返回所求距离。
解题比较复杂,思路:
1、前序遍历,保存遍历结果,以及各个节点的路径值,最大最小叶子值。
2、找出最大最小叶子在遍历结果的索引。
3、寻找最近公共祖先。按照遍历结果,如果一个在left/right后面,一个在right/left后面,则目前的节点便是结果,否则继续左或右寻找。
4、找到后将三个节点的路径值找出。
/*struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) { }};*/class Tree {public: int getDis(TreeNode* root) { // write code here stack<pair<TreeNode*,int>> st; st.push({root,0}); TreeNode *cur; vector<int> pre,node; vector<pair<int,int>> vp; int maxn{0},minn{0}; while(!st.empty())//DFS--preorder { auto p=st.top(); cur=p.first; vp.push_back({cur->val,p.second}); st.pop(); pre.push_back(cur->val); if(cur->right) st.push({cur->right,p.second+1}); if(cur->left) st.push({cur->left,p.second+1}); if(!(cur->left||cur->right)) { if(maxn==0&&minn==0) { maxn=minn=cur->val; } else { maxn=max(maxn,cur->val); minn=min(minn,cur->val); } } } stack<TreeNode*> st1; st1.push(root); int curpos{},maxpos{-1},minpos{-1},sz=pre.size(); for(int i=0;i<sz&&(maxpos==-1||minpos==-1);++i) { if(pre[i]==maxn) { maxpos=i; } if(pre[i]==minn) { minpos=i; } } while(!st1.empty()) { cur=st1.top(); st1.pop(); int left{-1},right{-1},leftpos{-1},rightpos{-1}; if(cur->right) { right=cur->right->val; st1.push(cur->right); } if(cur->left) { left=cur->left->val; st1.push(cur->left); } for(int i=curpos;i<sz;++i) { if(left!=-1&&pre[i]==left) { leftpos=i; } if(right!=-1&&pre[i]==right) { rightpos=i; } } if(leftpos!=-1&&rightpos!=-1) { if(maxpos<rightpos&&minpos<rightpos) { curpos=leftpos; } else if(maxpos>rightpos&&minpos>rightpos) { curpos=rightpos; } else { curpos=pre[curpos];//更新为对应值 break; } } } int minl{-1},maxl{-1},fl{-1}; sz=vp.size(); for(int i=0;i<sz&&(minl==-1||maxl==-1||fl==-1);++i) { if(minl==-1&&vp[i].first==minn) { minl=vp[i].second; } if(maxl==-1&&vp[i].first==maxn) { maxl=vp[i].second; } if(fl==-1&&vp[i].first==curpos) { fl=vp[i].second; } } return maxl-fl+minl-fl; }};
看一下别人的代码:@NoYes_Li
这段java代码我看了很久,主要是被一个函数给暗算了,
maxcodec.charAt(index),他的索引是字符串的低位开始,类似数组,不要从自己的低位!
为什么二进制编码可以呢,显然,在这里,他将相同前缀去掉就是找到了父节点的编码(他的编码是左走加0,右走加1),在这里除去前缀的长度就是该节点到父节点的距离,两者距离相加就是路径长度了。
//典型的二进制编码题,算出叶子节点二进制编码,再比编码,计算后缀长度和import java.util.*;/*public class TreeNode { int val = 0; TreeNode left = null; TreeNode right = null; public TreeNode(int val) { this.val = val; }}*/public class Tree { private int max=0; private int min=99999; private StringBuilder maxcodec; private StringBuilder mincodec; void PreOrder(TreeNode T,char code,StringBuilder codec){ if(T!=null){ codec.append(code); if(T.left==null && T.right==null) { if(max<T.val) { max=T.val; maxcodec = codec; } if(min>T.val) { min=T.val; mincodec = codec; } } PreOrder(T.left,'0',new StringBuilder(codec)); PreOrder(T.right,'1',new StringBuilder(codec)); } } public int getDis(TreeNode root) { PreOrder(root,'0',new StringBuilder()); int index=0; for(index=0; index<(maxcodec.length()>mincodec.length()?maxcodec.length():mincodec.length());index++) { if(maxcodec.charAt(index)!=mincodec.charAt(index)) break; } return (maxcodec.substring(index).length()+mincodec.substring(index).length()); // write code here }};
寻找第K大
有一个整数数组,请你根据快速排序的思路,找出数组中第K大的数。
给定一个整数数组a,同时给定它的大小n和要找的K(K在1到n之间),请返回第K大的数,保证答案存在。
测试样例:
[1,3,5,2,2],5,3
返回:2
类快排思想:
1、找出枢纽点,比如按照三点中值可以找出。
2、当数组比较小时,可以采取插入排序等寻找,此处可以改进。
3、将中值放在数组尾部前,可以将剩余元素方便归类。
4、还原中值,开始递归。
代码反思:
vector<int> small(a.begin(),a.begin()+i),big(a.begin()+i+1,a.end()); int bsz=big.size(),ssz=small.size(); if(bsz>=K){ return findKth(big,bsz,K); } else if(bsz==K-1){ for(int i=0;i<14;++i){ cout<<a[i]<<endl; } return a[i]; } else{ return findKth(small,ssz,K-bsz); }
最开始我的递归部分是这样写的,妄想像快排一样,忽略已经定序的枢纽元素,但是,结果错误。后来将该元素归入大的一类才正确,经过IDE调试,发现如果不考虑该元素,就相当与后面你的数组里面少了一个元素,这是致命的。可能会在后面算大小与K比较时候出现问题。
如:
1,2,2,4,3,7,8,9,1,10,8,9找第7
中值7,此时1,2,2,4,3,1一组,8,9,10,8,9一组
1,2,2,4,3,1找第7-5=2
中值1,此时1一组,2,2,3,4一组
得到3。错误。
实际应该是4。
中值7,此时1,2,2,4,3,1一组,7,8,9,10,8,9一组
1,2,2,4,3,1找第7-6=1
中值1,此时1一组,2,2,3,4一组
得到4。正确。
此处应该把值放入,但是依旧可以那么返回。
后期注释掉的代码应该是多余的。
class Finder {public: int findKth(vector<int> a, int n, int K) { // write code here // if(n==0) return 0;后期注释掉的,应该不需要 // if(n==1) return a[0]; if(n<10){ sort(a); return a[K-1]; } int pivot=median3(a,n); int i=0,j=n-2; for(;;){ while(a[++i]<pivot); while(pivot<a[--j]); if(i<j){ swap(a[i],a[j]); } else{ break; } } swap(a[i],a[n-2]); vector<int> small(a.begin(),a.begin()+i),big(a.begin()+i,a.end()); int bsz=big.size(),ssz=small.size(); if(bsz>=K){ return findKth(big,bsz,K); } else{ return findKth(small,ssz,K-bsz); } }private: int median3(vector<int> &a,int n){ int mid=n/2; if(a[mid]<a[0]) swap(a[mid],a[0]); if(a[n-1]<a[0]) swap(a[0],a[n-1]); if(a[n-1]<a[mid]) swap(a[n-1],a[mid]); swap(a[mid],a[n-2]); return a[n-2]; } void sort(vector<int> &a){//select_sort int sz=a.size(); for(int i=0;i<sz;++i){ int maxp=i; for(int j=i+1;j<sz;++j){ if(a[j]>a[maxp]){ maxp=j; } } swap(a[i],a[maxp]); } }};
- 网易2016 实习研发工程师编程题
- 网易2016实习研发工程师编程题
- 网易2016实习研发工程师编程题
- 网易 2016 实习研发工程师 3道 编程题
- 牛客网之网易2016实习研发工程师编程题
- 比较重量----网易2016实习研发工程师编程题
- 二叉树 网易2016实习研发工程师编程题
- 网易2016实习研发工程师编程题——寻找第K大
- 网易2016研发工程师编程题
- 网易2016研发工程师编程题
- 网易2016研发工程师编程题 搜索
- 网易2016研发工程师编程题①
- 网易2016研发工程师编程题②
- 网易2016研发工程师编程题
- 试卷: 网易2016研发工程师编程题
- 网易2016研发工程师编程题
- 网易2016研发工程师编程题
- 网易2016研发工程师编程题
- 怎么卸载oracle
- Light OJ 1275 Internet Service Providers (数学)
- NYOJ-27水池数目
- Android中级:事件传递机制
- 运动估计和运动补偿
- 网易2016实习研发工程师编程题
- POJ 2533 Longest Ordered Subsequence(基础DP)
- Leetcode 55. Jump Game (Medium) (cpp)
- Hibernate学习笔记
- 数据结构实验之栈二:一般算术表达式转换成后缀式 (sdut oj 2132)
- NYOJThe partial sum problem927
- android的xml动画入门
- 最长上升子序列详解(nlogn)
- 【HDU】-2717-Catch That Cow(BFS)