【精】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/ 博客原创,转载请注明来源,谢谢~

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

二当家的白帽子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值