摘取最多蘋果數

某企業校招的編程題目,問題大致描述如下:

有一棵樹有N個節點,其中有K個節點有蘋果。在每條邊至多走一次的情況下,最多可以摘到的蘋果數。其中,可以從任意一個節點出發。

實現代碼如下:

import java.util.*;

public class Main {
    public static void main(String[] args) {
       Solution s=new Solution();
//       int a[]={2,3,4};
//       int b[][]={{1,2},{1,3},{1,4}};
       int a[]={2,3,5,6};
       int b[][]={{1,2},{1,3},{2,5},{2,4},{3,6},{3,7},{6,8}};
       int res = s.collectApples(8, 4,a ,b); 
       System.out.println(res);
    }    
}

class Node{
    private boolean at;//是否訪問過
    private int num;//節點值
    private boolean apple;//是否有蘋果
    //保存關聯節點
    List<Node> childs=new ArrayList<Node>();
    
    public Node(Node p, boolean a,int num){
        this.apple=a;
        this.num=num;
    }

    public void add(Node node){
        this.childs.add(node);
    }
    public boolean isAccess(){
    	return this.at;
    }
    public boolean existApple(){
    	return this.apple;
    }
    public void noAccess(){
    	this.at=false;
    }
    public void access(){
    	this.at=true;
    }
    //打印時的合理輸出
    public String toString(){
    	return String.valueOf(num);
    }
    //測試節點內部構造的關聯節點是否正確
    public void printChilds(){
    	for (int i = 0; i < childs.size(); i++) {
			System.out.print(childs.get(i)+",");
		}
    	System.out.println();
    }
}
class Solution
{
      int collectApples(int N, int K, int[] applesAtNodes, int[][] connectedNodes)     
      {
         Map<Integer, Node> map=new HashMap<Integer, Node>();
         //首先實例化有蘋果的節點
         for(int i=0;i<K;i++){
             int cur = applesAtNodes[i];
             Node node=new Node(null,true,cur);
             map.put(cur,node);
         }
        int m=connectedNodes.length;
//        System.out.print(map);
        //根據是否有邊,構造圖結構
        for(int i=0;i<m;i++){
            int pNum=connectedNodes[i][0];
            int cNum=connectedNodes[i][1];
            Node pn;
            Node cn;
            if(map.containsKey(pNum)){
                pn=map.get(pNum);
            }else{
                pn=new Node(null,false,pNum);
                map.put(pNum, pn);
            }
            if(map.containsKey(cNum)){
                cn=map.get(cNum);
            }else{
                cn=new Node(pn,false,cNum);
                map.put(cNum, cn);
            }
            //通過任何一方找到另一方,必須各自擁有對方
            pn.add(cn);
            cn.add(pn);
        }
        int max=-1;
        //System.out.println(map);//打印構造的map
        for(Node node:map.values()){
        	//測試構造的圖結構是否正確
//        	System.out.println("node:"+node);
//        	node.printChilds();
        	//重新一輪之前,重置所有節點未遍歷過
        	resetNoAccess(map);
            int num1=search(node);//計算以從節點出發的摘取的最大蘋果樹
//            System.out.println("num1:"+num1+",max:"+max);
            max=Math.max(max,num1);
        }
        return max;
      }
      //重置map中節點的是否訪問屬性
      void resetNoAccess(Map<Integer, Node> map){
    	  for(Node node:map.values()){
    		  node.noAccess();
    	  }
      }
      //以某個節點出發遞歸,計算最大可摘取蘋果樹
      int search(Node node){
          if(node==null || node.isAccess())return 0;
          node.access();
          //深度遍歷未訪問的關聯節點
          int num2=0;
          for(int i=0;i<node.childs.size();i++){
             int cur=search(node.childs.get(i));
             num2=Math.max(cur,num2);
          }
          if(node.existApple())return 1 + num2;//有蘋果的情況
          else return num2;
      }
  }


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章