1. 程式人生 > >華為筆試題:最短路徑問題---出差遇上大霧

華為筆試題:最短路徑問題---出差遇上大霧

問題描述

思路分析

  • 這個題其實就是求最短路徑的問題,常見的演算法有兩種,dijkstra演算法和floyd演算法
  • 在本例中使用的是後者floyd演算法,時間複雜度O(N^3),空間複雜度O(N^2)
  • 使用它的原因是因為,這個演算法十分之優雅,核心程式碼只有五行,寫起來暢快無比。

程式碼展示

package com.huawei.test;

import java.util.ArrayList;
import java.util.Scanner;

public class Demo7 {
    // 兩個陣列,一個用來儲存任意兩個城市的最短距離,一個用來儲存路徑
    private static Integer[][] dist;
    private static Integer[][] path;
    // 定義不可達的距離為1000
    private final static int INF = 1000;

    public static void main(String[] args) {
        int beginCity = 5 - 1;// 出發城市
        int size = 6;
        Scanner sc = new Scanner(System.in);
        int endCity = sc.nextInt() - 1;// 因為儲存在陣列中,所以要減一
        int foggyCity = sc.nextInt() - 1;// 因為儲存在陣列中,所以要減一
        // 初始矩陣,表示各個城市之間的距離
        Integer[][] matrix = { { 0, 2, 10, 5, 3, INF }, { INF, 0, 12, INF, INF, 10 }, { INF, INF, 0, INF, 7, INF },
                { 2, INF, INF, 0, 2, INF }, { 4, INF, INF, 1, 0, INF }, { 3, INF, 1, INF, 2, 0 } };
        // 初始化那兩個陣列
        dist = new Integer[size][size];
        path = new Integer[size][size];
        // 設定起霧城市
        if (foggyCity != 0) {
            setFoggyCity(foggyCity, matrix);
        }
        // 使用floyd演算法
        floyd(matrix);
        // 距離
        System.out.println(dist[beginCity][endCity]);
        // 路徑
        ArrayList<Integer> list = new ArrayList<>();
        findPath(beginCity, endCity, list);
        // 路徑每個值加1
        for (int i = 0; i < list.size(); i++) {
            list.set(i, list.get(i) + 1);
        }
        if (dist[beginCity][endCity] == INF) {
            list.removeAll(list);
        }
        System.out.println(list);
    }

    // 除錯,m沒有呼叫該函式,不懂的可以用這個函式列印陣列dist\path就會清除了
    public static void printMatrix(Integer[][] matrix) {
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix.length; j++)
                System.out.print(matrix[i][j] + " ");
            System.out.println();
        }
    }

    private static void findPath(int beginCity, int endCity, ArrayList<Integer> list) {
        list.add(beginCity);
        while (path[beginCity][endCity] != -1) {
            int midCity = path[beginCity][endCity];
            list.add(midCity);
            beginCity = midCity;
        }
        list.add(endCity);
    }

    /**
     * 最核心的輔助函式
     * 
     * @param matrix
     */
    private static void floyd(Integer[][] matrix) {
        int size = matrix.length;
        // 為輔助陣列賦值
        for (int i = 0; i < size; i++) {
            for (int j = 0; j < size; j++) {
                dist[i][j] = matrix[i][j];
                path[i][j] = -1;
            }
        }
        // floyd演算法
        for (int k = 0; k < size; k++) {
            for (int i = 0; i < size; i++) {
                for (int j = 0; j < size; j++) {
                    if (dist[i][j] > dist[i][k] + dist[k][j]) {
                        dist[i][j] = dist[i][k] + dist[k][j];
                        path[i][j] = k;
                    }
                }
            }
        }
    }

    // 設定起霧城市
    private static void setFoggyCity(int foggyCity, Integer[][] matrix) {
        for (int i = 0; i < matrix.length; i++) {
            matrix[i][foggyCity] = INF;
            matrix[foggyCity][i] = INF;
        }
    }

}