精LintCode领扣算法问题答案:1891 · 旅行计划

Posted 二当家的白帽子

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了精LintCode领扣算法问题答案:1891 · 旅行计划相关的知识,希望对你有一定的参考价值。

1891 · 旅行计划:

有n个城市,给出邻接矩阵arr代表任意两个城市的距离。arr[i][j]代表从城市i到城市j的距离。Alice在周末制定了一个游玩计划,她从所在的0号城市开始,游玩其他的1 ~ n-1个城市,最后回到0号。Alice想知道她能完成游玩计划需要行走的最小距离。返回这个最小距离。除了城市0之外每个城市都只能经过一次,且城市0只能是起点和终点,Alice中途不可经过城市0。

  • n <= 10
    arr[i][j] <= 10000

样例 1

输入:
	[[0,1,2],[1,0,2],[2,1,0]]
输出:
	4
解释:
	[[0,1,2],
	 [1,0,2],
	 [2,1,0]]
	有两种可能的方案。
	第一种,城市0->城市1->城市2->城市0,cost=5。
	第二种,城市0->城市2->城市1->城市0,cost=4。
	返回4

样例 2

输入:
	[[0,10000,2],[5,0,10000],[10000,4,0]]
输出:
	11

原题传送门



分析

除了遍历所有可能性,我没有想到更好的办法,如果有人有更好的想法,请一定要分享给我,谢谢。虽然是遍历所有可能性,但是我还是进行了一定的优化,如果当前的花费超过之前的最小花费那就没必要继续尝试下去了。

题解

public class Solution {
    /**
     * @param arr: the distance between any two cities
     * @return: the minimum distance Alice needs to walk to complete the travel plan
     */
    public int travelPlan(int[][] arr) {
        // Write your code here.

        // 众所周知,java是面向对象的,所以返回结果我不用实例变量
        // 面向对象的指针
        Pointer<Integer> minCost = new Pointer<>(Integer.MAX_VALUE);

        // 魔法
        dfs(arr, new boolean[arr.length], 1, 0, 0, minCost);

        return minCost.getV();
    }

    /**
     * 深度优先的套娃大法(递归算法)
     * @param arr
     * @param vis 去过哪些城市
     * @param count 去过几个城市
     * @param from 目前在哪个城市
     * @param cost 目前的花费
     * @param minCost 最小花费
     */
    private void dfs(int[][] arr, boolean[] vis, int count, int from, int cost, Pointer<Integer> minCost) {
        // 超过最小花费就跳过
        if (cost >= minCost.getV()) {
            return;
        }
        if (count == arr.length) {
            // 返回
            cost += arr[from][0];
            minCost.setV(Math.min(cost, minCost.getV()));
        } else {
            // 没有魔法了,把没试过的都试试
            for (int to = 1; to < arr.length; ++to) {
                if (!vis[to]) {
                    vis[to] = true;
                    dfs(arr, vis, count + 1, to, cost + arr[from][to], minCost);
                    vis[to] = false;
                }
            }
        }
    }

    /**
    * 面向对象的指针
    * @param <T>
    */
    class Pointer<T> {
        private T v;

        public Pointer(T v) {
            this.v = v;
        }

        public T getV() {
            return v;
        }

        public void setV(T v) {
            this.v = v;
        }
    }
}


最后说两句

非常感谢你阅读本文章,如果你觉得本文对你有所帮助,请留下你的足迹,点个赞,留个言,多谢~

作者水平有限,如果文章内容有不准确的地方,请指正。

希望小伙伴们都能每天进步一点点。

本文由 二当家的白帽子 https://le-yi.blog.csdn.net/ 博客原创,转载请注明来源,谢谢~

以上是关于精LintCode领扣算法问题答案:1891 · 旅行计划的主要内容,如果未能解决你的问题,请参考以下文章

精LintCode领扣算法问题答案:入门

精LintCode领扣算法问题答案:1890. 形成最小数

精LintCode领扣算法问题答案:1890. 形成最小数

精LintCode领扣算法问题答案:1892 · 扫雷

精LintCode领扣算法问题答案:1889. 区间合并

精LintCode领扣算法问题答案:1889. 区间合并