首页 > 试题广场 >

现在你的任务是完成getValidOrder函数,如果有合法

[问答题]
小米公司内部每个员工都会有一个专属的工作邮箱,邮箱的前缀是员工姓名的拼音全拼,例如张强的邮箱是zhangqiang@xiaomi.com,但同时公司里有很多同名的人,为了避免大家相互之间发错邮件,工程师们想了个规则来解决这个问题,即在这些同命人中,入职最早的邮箱前缀为姓名的拼音全拼,第二个入职的邮箱前缀为姓名的拼音全拼后面加“_a”,第三个入职的为姓名的拼音全拼后面加“_b”,以次类推,请按这个规则,如果公司里同时有3位名叫张强的员工,则他们的邮箱分别是zhangqiang@xiaomi.com,zhangqiang_a@xiaomi.com,zhangqiang_b@xiaomi.com...邮箱前缀是员工在公司里的重要标识之一,问题来了:现在小米要举行一次全员野外拉练活动,要求所有员工必须排成一队出去,并且,有的员工要求他必须排在某人的前面或后面,作为组织者的你,收到这样的需求之后,如何给出一个让每个人都满意的排队方式呢?
Java:
class RequestItem
{
    public String member;
    public boolean standFront; //true表示要排在这个人的前面,false表示要排在这个人的后面
}
class Request
{
    public String owner;    //那个人提出的要求
    List<RequestItem> requestItems;    //他要排在哪些人的前面,哪些人的后面
}
List<String> getValidOrder(List<String>allMembers, List<Request> requests);
allMembers就是所有员工的邮箱前缀,requests是一些人的排队要求。小米公司现有几千名员工,每个人最多有10个排队要求(要排在一个人的前面或者后面算一个排队要求),也有人没有什么要求。现在你的任务是完成上面的getValidOrder函数,如果有合法的排队序列,那么返回其中任何一个。否则返回null。
腾讯的笔试题为什么会出现小米?
发表于 2015-08-31 10:26:54 回复(2)
这个应该是一个拓扑排序的思想,综合所有人的要求,a要求排在b前面即a指向b的边存在,最终可以生成一个有向图。并在统计条件时统计每个顶点的入度,然后进行拓扑排序。
思想大致如下:首先查找所有入度为0的顶点,如果没有则不存在合法的排队序列,返回null,存在的话放在一个临时队列中。
然后把list中一个员工放进 List<String>中,并把跟该节点相关的节点入度减一,查找是否有节点入度变成了0,有的话把该节点放入list继续遍历,如果没有则查看临时队列
是否还有节点,有的进行遍历,没有的话,如果还有节点没有遍历则返回null。如果所有节点遍历完成则返回list
发表于 2015-09-02 16:25:10 回复(1)
假设有n个员工。
选用数据结构,map[n][n]。
1、其中map[i][j]=1代表i在j的前面,=0代表前后位置,=-1带表在后面。若出现已经=-1的情况下,在后面又要求=1,会形成环,则返回null。。
2、这样就形成了一个图,然后进行拓扑排序即可。先找出所有入度为0的点,放在前面,然后去掉这些点和相应的边.如此得到最终结果。

欢迎找出问题!!
发表于 2015-04-05 01:09:31 回复(3)
import java.util.ArrayList;
import java.util.List;

/**
 * guohui.zhu
 * qq:775737814
 *  欢迎指教 
 */
public class Px {
    private List<String> orders=new ArrayList<String>();
    public static void main(String[] args)
    {
        Px p=new Px();
        List<String>allMembers=new ArrayList<String>();
        allMembers.add("a");
        allMembers.add("b");
        allMembers.add("c");
        allMembers.add("d");
        List<Request> ls=new ArrayList<Request>();
        ls.add(getNewRequest("a"));
        ls.get(0).requestItems.add(getNewRequestItem("b",true));
        ls.get(0).requestItems.add(getNewRequestItem("c",false));
        ls.add(getNewRequest("b"));
        ls.get(1).requestItems.add(getNewRequestItem("a",true));
        ls.get(1).requestItems.add(getNewRequestItem("c",false));
        List<String> orders= p.getValidOrder(allMembers,ls);
        System.out.println(orders);
    }
    private static Request getNewRequest(String owner)
    {
        Request obj=new Request();
        obj.owner=owner;
        obj.requestItems=new ArrayList<RequestItem>();
        return obj;
    }
    private static RequestItem getNewRequestItem(String member,boolean frant)
    {
        RequestItem obj=new RequestItem();
        obj.member=member;
        obj.standFront=frant;
        return obj;
    }
    /**
     * @param allMembers  参与排序的所有的成员
     * @param requests       请求排序的条件,每个request不能为空
     * @return
     */
    public List<String> getValidOrder(List<String>allMembers, List<Request> requests)
    {
        if(requests==null||requests.size()==0) return allMembers; 
        if(isOk(allMembers,requests))  
        {
            return orders;
        }
        return null;
    }
    private boolean isOk(List<String>allMembers,List<Request> requests)
    {
         if(allMembers.size()==1)
         {
             orders.add(allMembers.get(0));
             return true;
         }
         List<String> delete=new ArrayList<String>();
         for(int i=0;i<requests.size();i++)
         {
              for(int j=0;j<requests.get(i).requestItems.size();j++)
              {
                    //owner要求排在这个人的后面,证明owner是没有资格在本局进行排序
                    if(!requests.get(i).requestItems.get(j).standFront)   
                    {
                         if(!delete.contains(requests.get(i).owner))
                         {
                              delete.add(requests.get(i).owner); 
                         }
                    }
                    else
                    {
                         //owner要求排在这个人的前面,说明至少这个人在本局是没有资格进行排序
                         if(!delete.contains(requests.get(i).requestItems.get(j).member))
                         {
                             delete.add(requests.get(i).requestItems.get(j).member);
                         }
                    }
              }
         }
         if(delete.size()==allMembers.size())
         {
             //出现了环形的闭合回路
             return false;
         }
         allMembers.removeAll(delete);  //排除不能在本局排序的,其余的都可以在本局任意位置出现
         orders.addAll(allMembers);
         List<Request> reqnew=new ArrayList<Request>();
         for(int j=0;j<requests.size();j++)
          {
                if(!allMembers.contains(requests.get(j).owner)) 
                {
                     reqnew.add(requests.get(j));
                     for(int i=0;i<requests.get(j).requestItems.size();i++)
                     {
                         if(allMembers.contains(requests.get(j).requestItems.get(i).member))
                         {
                              reqnew.get(reqnew.size()-1).requestItems.remove(requests.get(j).requestItems.get(i));
                         }
                     }
                }
          }
         return isOk(delete,reqnew);  //递归调用
    }
}
class RequestItem
{
    public String member;
    public boolean standFront; //true表示要排在这个人的前面,false表示要排在这个人的后面
}
class Request
{
    public String owner;    //那个人提出的要求
    List<RequestItem> requestItems;    //他要排在哪些人的前面,哪些人的后面
}
编辑于 2015-06-04 00:15:31 回复(0)
我很想知道 如果A要求排在B前面 ,B要求排在A前面 这题怎么做? 还是我理解错题意了?
发表于 2017-11-20 12:25:21 回复(1)
#include<iostream>
#include<string>
#include<vector>
#include<iterator>
#include<algorithm>
using namespace std;

class RequestItem
{
public:
	string member;
    bool standFront; //true表示要排在这个人的前面,false表示要排在这个人的后面
};
class Request
{
public:
	string owner;    //那个人提出的要求
    vector<RequestItem> requestItems;    //他要排在哪些人的前面,哪些人的后面
};

typedef struct node
{
  int adjent;
  struct node* next;
}*graphnode;

typedef struct elem
{
  int in;
  graphnode first;  
}graphelem;

vector<string> getValidOrder(vector<string>& m, vector<Request>& r)
{
  int len=m.size();
  graphelem* gra=new graphelem[len];
  size_t i,j;
  vector<string>::iterator ite1=m.begin(),ite2,ite3;
  int index1,index2;
  for(i=0;i<len;++i)
    gra[i].in=0;
  for(i=0;i<r.size();++i)
   {
           ite2=find(m.begin(),m.end(),r[i].owner);   
	    index1=ite2-ite1;                          //要求者 A
        for(j=0;j<r[i].requestItems.size();++j)
         {	
	         ite3=find(m.begin(),m.end(),r[i].requestItems[j].member); 	 
	         index2=ite3-ite1;                           //被要求者 B	   
             if(r[i].requestItems[j].standFront)  //A->B    
              {		
			       gra[index2].in++;
			       graphnode tmp= new struct node;
			       tmp->next=gra[index1].first;
			       tmp->adjent=index2;
			       gra[index1].first=tmp;
	       }
	     else                              //B->A
	          {	        
			       gra[index1].in++;
		           graphnode tmp= new struct node;
			       tmp->next=gra[index2].first;
			       tmp->adjent=index1;
			       gra[index2].first=tmp;
	          }
	  }
     }
   int* s=new int[len];    //拓扑排序
   int top=-1,count=0,tmp;
   vector<string> res;
   for(i=0;i<len;++i)
    if(gra[i].in==0)
      s[++top]=i;
   while(top!=-1)
   {
     tmp=s[top--];
     res.push_back(m[tmp]);
	 ++count;
	 for(graphnode p=gra[tmp].first;p;p=p->next)
	 {
	   if(--gra[p->adjent].in==0)
	     s[++top]=p->adjent;
	 }
   }  
   if(count<len)	 
	 res.clear();
	return res;	       
}
发表于 2017-04-05 20:25:54 回复(2)
拓排+1
发表于 2015-09-02 15:36:40 回复(0)
拓扑排序。
发表于 2015-08-27 14:39:11 回复(0)
如果甲要求排在乙的前面,而已也要求排在甲的前面怎么解决呢?这个怎么满足要求?新人不懂,求轻喷
编辑于 2015-05-24 10:00:10 回复(1)