某互联网公司2014 Java工程师面试试题

题目链接

题目描述:

在A,B两个城市之间设有N个路站(如下图中的S1,且N<100),城市与路站之间、路站和路站之间各有若干条路段(各路段数≤20,且每条路段上的距离均为一个整数)。
A,B的一条通路是指:从A出发,可经过任一路段到达S1,再从S1出发经过任一路段,…最后到达B。通路上路段距离之和称为通路距离(最大距离≤1000)。当所有的路段距离给出之后,求出所有不同距离的通路个数(相同距离仅记一次)。
例如:下图所示是当N=1时的情况:

从A到B的通路条数为6,但因其中通路5+5=4+6,所以满足条件的不同距离的通路条数为5。

数据结构:             

N记录A,B间路站的个数                                     

D[I][0]记录第I-1到第I路站间路段的个数                                   

 D[I][1],D[I][2]……记录每个路段距离

G[X]标记长度为X的通路是否可能

B数组在穷举过程中记录当前路

B[I]表示第I-1到第I路站之间选择哪一条路段


思路1:递归求解

思路2:迭代求解



源代码:

package com.sum;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Random;
import java.util.Scanner;
import java.util.Set;
/**
 * 题目描述:

在A,B两个城市之间设有N个路站(如下图中的S1,且N<100),城市与路站之间、路站和路站之间各有若干条路段(各路段数≤20,且每条路段上的距离均为一个整数)。
A,B的一条通路是指:从A出发,可经过任一路段到达S1,再从S1出发经过任一路段,…最后到达B。通路上路段距离之和称为通路距离(最大距离≤1000)。当所有的路段距离给出之后,求出所有不同距离的通路个数(相同距离仅记一次)。
例如:下图所示是当N=1时的情况:
 * */
public class MaxRoadCount {
	public static final int MAX_LOAD_COUNT=21;
	public static int MAX_LOAD_SUM=1000;
	public static int MAX_NODE_COUNT=100;
	static Set<Integer> resultSet=new HashSet<Integer>();
	
	int N;//A、B两城市中间的结点数
	int D[][];//记录路段(结点)间的个数
	//D[I][0]  I-1~I路段个数
	//D[I][1] D[I][2] 路段距离
	int G[]=new int[1000];
	int B[];
	public static void main(String[] args) {
		MaxRoadCount st=new MaxRoadCount();
		st.init2();
		long start=System.currentTimeMillis();
		st.fun();
		long end=System.currentTimeMillis();
		System.out.println("所花时间:"+(end-start)+"ms");
	}
 	public void init2(){
 		N=100;
		generateNode(N);
		B=new int[MAX_LOAD_SUM];
	}
	public  void generateNode(int n){
		D=new int[n+1][];
		Random r=new Random();
		for(int i=0;i<n+1;i++){
//			int count=1+r.nextInt(20);
			int count=20;
			D[i]=new int[count+1];
			D[i][0]=count;
			for(int j=1;j<=count;j++){
				D[i][j]=1+r.nextInt(10);
			}
		}
		System.out.println("生成输出:");
		for(int i=0;i<n+1;i++){
			for(int j=1;j<=D[i][0];j++){
				System.out.print(D[i][j]);
			}
			System.out.println();
		}
	}
	public  void input(){
		Scanner s =new Scanner(System.in);
		N=s.nextInt();
		if(N<1||N>=MAX_NODE_COUNT)
		{
			System.out.println("Error");
			return;
		}
		D=new int[N+1][];
		for(int i=0;i<N+1;i++){
			D[i][0]=s.nextInt();
			if(D[i][0]<1||D[i][0]>MAX_LOAD_COUNT)
			{
				System.out.println("Error");
				return;
			}
			for(int j=1;j<=D[i][0];j++){
				D[i][j]=s.nextInt();
			}
		}
//		System.out.println(D.length);
	}
	public  void fun(){
		int distance=0;
		int i=-1;
		long start=System.currentTimeMillis();
		findRoad(i+1,distance);
		long end=System.currentTimeMillis();
//		
		System.out.println("递归所花时间"+(end-start)+"ms");
		
//		int sum=0;
//		for(int j=0;j<MAX_LOAD_SUM;j++)
//			sum+=G[j];
		System.out.println("结果1:"+resultSet.size());
		List<Integer> list=new ArrayList<Integer>(resultSet);
		for(int j=0;j<list.size();j++)
			System.out.print(list.get(j)+",");
		System.out.println();
		
		
		start=System.currentTimeMillis();
		findRoadWithFor();
		end=System.currentTimeMillis();
		System.out.println("迭代所花时间"+(end-start)+"ms");
		
	}
	public void findRoadWithFor(){
//		int a[]=D[0];
		int a[]={};
		for(int i=0;i<N+1;i++){
			a=findSumRoadDistance(a,D[i]);
		}
		System.out.println("结果2:"+a.length);
		for(int j=0;j<a.length;j++){
			System.out.print(a[j]+",");
		}
		System.out.println();
	}
	/**
	 * 前一个路段的所有路长,和后一个路段的所有路长两两相加
	 * 去除重复
	 * */
	public int[] findSumRoadDistance(int a[],int d[]){
		Set<Integer> set=new HashSet<Integer>();
		if(a.length==0){
			for(int j=1;j<d.length;j++)
				set.add(d[j]);
		}else {
			for(int i=0;i<a.length;i++){
				for(int j=1;j<d.length;j++)
					set.add(a[i]+d[j]);
			}
		}
		
		
		Integer objects[]=(Integer[])set.toArray(new Integer[0]);
		int result[]=new int[objects.length];
		for(int i=0;i<result.length;i++)
			result[i]=objects[i];
		return result;
	}
	public  void findRoad(int node,int distance){
		if(node==N+1)
		{
			if(distance>MAX_LOAD_SUM)
				return;
//			System.out.println(distance);
//			System.out.println(resultSet.size());
			resultSet.add(distance);
//			G[distance]=1;
			return;
		}
		for(int j=1;j<=D[node][0];j++){
//			System.out.println(node);
			B[node]=j;
			findRoad(node+1, D[node][j]+distance);
		}
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值