[编程题]寻找第K大
有一个整数数组,请你根据快速排序的思路,找出数组中第K大的数。
给定一个整数数组a,同时给定它的大小n和要找的K(K在1到n之间),请返回第K大的数,保证答案存在。
测试样例:
[1,3,5,2,2],5,3
返回:2
class Finder { public: int findKth(vector<int> a, int n, int K) { // write code here return find(a,0,n-1,K); } int find(vector<int>& a, int left, int right, int K) { int begin=left; int end=right; int flag=a[left]; while(left<right) { while(left<right&&a[right]<=flag) right--; if(left<right) a[left++]=a[right]; while(left<right&&a[left]>=flag) left++; if(left<right) a[right--]=a[left]; } a[left]=flag; if(left-begin==K-1) return a[left]; else if(left-begin>K-1) return find(a,begin,left-1,K); else return find(a,left+1,end,K-(left-begin)-1); } };
剑指offer上的解法如下,更加的简洁:
class Finder { public: int findKth(vector<int> a, int n, int K) { // write code here int start=0; int end=n-1; int index=find(a,0,n-1); while(index!=K-1) { if(index>K-1) { end=index-1; index=find(a,start,end); } else if(index<K-1) { start=index+1; index=find(a,start,end); } } return a[index]; } int find(vector<int>& a, int left, int right) { int begin=left; int end=right; int flag=a[left]; while(left<right) { while(left<right&&a[right]<=flag) right--; if(left<right) a[left++]=a[right]; while(left<right&&a[left]>=flag) left++; if(left<right) a[right--]=a[left]; } a[left]=flag; return left; } };
[编程题]二叉树
有一棵二叉树,树上每个点标有权值,权值各不相同,请设计一个算法算出权值最大的叶节点到权值最小的叶节点的距离。二叉树每条边的距离为1,一个节点经过多少条边到达另一个节点为这两个节点之间的距离。
给定二叉树的根节点root,请返回所求距离。
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
class Tree {
public:
vector<int> pathTemp;
public:
int getDis(TreeNode* root) {
// write code here
if(root==NULL)
return 0;
int Max=0x80000000,Min=0x7fffffff;
vector<int> pathMax,pathMin;
getMaxMin(root,Max,Min);
getPath(root,Max,pathMax);
pathMax=pathTemp;
pathTemp.clear();
getPath(root,Min,pathMin);
pathMin=pathTemp;
return getLc(pathMax,pathMin);
}
void getMaxMin(TreeNode* root,int&Max,int&Min){
if(root->left==NULL&&root->right==NULL)
{
if(root->val>Max)
Max=root->val;
if(root->val<Min)
Min=root->val;
return ;
}
if(root->left!=NULL)
getMaxMin(root->left,Max,Min);
if(root->right!=NULL)
getMaxMin(root->right,Max,Min);
return ;
}
void getPath(TreeNode* root,const int&num,vector<int>&res)
{
if(root==NULL)
return;
res.push_back(root->val);
if(root->left==NULL&&root->right==NULL)
{
if(root->val==num)
{
pathTemp=res;
return ;
}
}
else
{
if(root->left!=NULL)
getPath(root->left,num,res);
if(root->right!=NULL)
getPath(root->right,num,res);
}
res.pop_back();
return ;
}
int getLc(vector<int> pathMax,vector<int> pathMin)
{
int len1=pathMax.size();
int len2=pathMin.size();
int res=0;
if(len1>len2)
{
for(int i=0;i<len2;i++)
{
if(pathMax[i]!=pathMin[i])
{
res=i;
break;
}
}
}
else if(len1<=len2)
{
for(int i=0;i<len1;i++)
{
if(pathMax[i]!=pathMin[i])
{
res=i;
break;
}
}
}
return len1+len2-2*res;
}
};
//千万要注意最大值最小值的设定
[编程题]比较重量
小明陪小红去看钻石,他们从一堆钻石中随机抽取两颗并比较她们的重量。这些钻石的重量各不相同。在他们们比较了一段时间后,它们看中了两颗钻石g1和g2。现在请你根据之前比较的信息判断这两颗钻石的哪颗更重。
给定两颗钻石的编号g1,g2,编号从1开始,同时给定关系数组vector,其中元素为一些二元组,第一个元素为一次比较中较重的钻石的编号,第 二个元素为较轻的钻石的编号。最后给定之前的比较次数n。请返回这两颗钻石的关系,若g1更重返回1,g2更重返回-1,无法判断返回0。输入数据保证合 法,不会有矛盾情况出现。
测试样例:
2,3,[[1,2],[2,4],[1,3],[4,3]],4
返回: 1
class Cmp {
public:
int cmp(int g1, int g2, vector<vector<int> > records, int n) {
// write code here
map<int,vector<int>> res;
for(int i=0;i<n;i++)
res[records[i][0]].push_back(records[i][1]);
if(juge(g1,g2,res))
return 1;
else if(juge(g2,g1,res))
return -1;
else
return 0;
}
bool juge(const int &g1,const int &g2,map<int,vector<int>> res)
{
queue<int> q;
q.push(g1);
map<int,bool> mark;
while(!q.empty())
{
int cur=q.front();
q.pop();
mark[cur]=true;
if(cur==g2)
return true;
for(int i=0;i<res[cur].size();i++)
{
if(mark.find(res[cur][i])==mark.end())
q.push(res[cur][i]);
}
}
return false;
}
};
[编程题] 小易的升级之路
小易经常沉迷于网络游戏.有一次,他在玩一个打怪升级的游戏,他的角色的初始能力值为 a.在接下来的一段时间内,他将会依次遇见n个怪物,每个怪物的防御力为b1,b2,b3...bn. 如果遇到的怪物防御力bi小于等于小易的当前能力值c,那么他就能轻松打败怪物,并 且使得自己的能力值增加bi;如果bi大于c,那他也能打败怪物,但他的能力值只能增加bi 与c的最大公约数.那么问题来了,在一系列的锻炼后,小易的最终能力值为多少?
输入描述:
对于每组数据,第一行是两个整数n(1≤n<100000)表示怪物的数量和a表示小易的初始能力值. 第二行n个整数,b1,b2...bn(1≤bi≤n)表示每个怪物的防御力
输出描述:
对于每组数据,输出一行.每行仅包含一个整数,表示小易的最终能力值
输入例子:
3 50 50 105 200 5 20 30 20 15 40 100
#include<iostream> #include<vector> using namespace std; int getRes(const vector<int>&vec,const int& num,int b ); int main() { int num,b; while(cin>>num) { cin>>b; vector<int> vec(num); for(int i=0;i<num;i++) { cin>>vec[i]; } int res=getRes(vec,num,b); cout<<res<<endl; } return 0; } int getRes(const vector<int>&vec,const int& num,int b ) { for(int i=0;i<num;i++) { if(vec[i]<=b) b+=vec[i]; else { int small=b,big=vec[i]; int rest=big%small; while(rest!=0) { big=small; small=rest; rest=big%small; } b+=small; } } return b; }