首页
技术小册
AIGC
面试刷题
技术文章
MAGENTO
云计算
视频课程
源码下载
PDF书籍
「涨薪秘籍」
登录
注册
Bubble Sort - 冒泡排序
Selection Sort - 选择排序
Insertion Sort - 插入排序
Merge Sort - 归并排序
Quick Sort - 快速排序
Heap Sort - 堆排序
Bucket Sort
Counting Sort
两数之和
两数相加
无重复字符的最长子字符串
两个排序数组的中值
最长回文子串
锯齿形变换
反转整数
合并K个排序列表
链表循环
除Self之外的数组乘积
4的威力
蛙跳
将交叉口大小设置为至少两个
最大的块,使其分类
到达点
阶乘零点函数的前像大小
建造一个大的岛屿
唯一字母串
树的距离之和
猜词游戏
节点的最短路径
矩形区域II
K-相似字符串
雇佣K工人的最低成本
至少为K的最短子阵
获取所有key的最短路径
加油站的最小数量
有利可图的计划
细分图中的可达节点
超级蛋掉落
最大频率叠加
有序队列
DI序列的有效置换
猫和老鼠
最长不含重复字符的子字符串
丑数
第一个只出现一次的字符
字符流中第一个不重复的字符
两个链表的第一个公共结点
数字在排序数组中出现的次数
0到n-1中缺失的数字
数组中数值和下标相等的元素
二叉树的深度
数组中只出现一次的两个数字
数组中唯一只出现一次的数字
翻转单词顺序
左旋转字符串
滑动窗口的最大值
当前位置:
首页>>
技术小册>>
数据结构与算法(中)
小册名称:数据结构与算法(中)
难度: Hard 题意: 1. 给定一个图,问走遍所有的点的最短距离是多少 思路: - 这个题首先考虑一下dfs的做法。假设我们已经到达了m个点,下个点,我们需要枚举所有下个点没有被访问的点,进行访问遍历,直到所有的点都被访问到 - 我们注意到,枚举的过程中,需要枚举所有下个点没有被访问的点,而这个跟先前访问的顺序无关,也就是状态是一个访问集合,和当前到达的点共同组合而成的 - 我们注意到,枚举的过程中,状态是需要重复访问,因此我们利用记忆化搜索,保存中间结果,进行动态规划 - 这里需要注意的,我们可以预先把图形中两两最短距离先求出来缓存起来,这一部分只需要o(n^3)的复杂度 - 子问题是:f(set, last),set是访问集合,last是当前到达的点,函数值是达到当前状态最短距离 - 这里有个代码的实现方式,集合如何用实现?当然如果想实现一个具备集合特性的数据结构也是可以的,最简单的方式就是用bitset,也就是把集合的信息压缩在一个二进制串中,这个题的数据范围是n<=12,因此一个int就可以表达状态,状态总量是`2^n*n`,因此这个动态规划的时间复杂度是`o(2^n*n^2)` 代码: ```java class Solution { private int solve(int set, int last, int[][] dist, int[][] cache) { if (cache[set][last] != -1) { return cache[set][last]; } if (set == (1 << dist.length) - 1) { return cache[set][last] = 0; } int ret = 0x3fffffff; for (int i = 0;i < dist.length;i++) { if ((set & (1 << i)) == 0) { ret = Math.min(ret, dist[last][i] + solve(set + (1 << i), i, dist, cache)); } } return cache[set][last] = ret; } private int[][] calDist(int[][] graph) { int[][] dist = new int[graph.length][graph.length]; for (int i = 0;i < graph.length;i++) { for (int j = 0;j < graph.length;j++) { dist[i][j] = 0x3fffffff; } } for (int i = 0;i < graph.length;i++) { dist[i][i] = 0; for (int j = 0;j < graph[i].length;j++) { dist[i][graph[i][j]] = 1; } } for (int k = 0;k < graph.length;k++) { for (int i = 0;i < graph.length;i++) { for (int j = 0;j < graph.length;j++) { dist[i][j] = Math.min(dist[i][j], dist[i][k] + dist[k][j]); } } } return dist; } public int shortestPathLength(int[][] graph) { int[][] cache = new int[1 << graph.length][graph.length]; for (int i = 0;i < (1 << graph.length);i++) { for (int j = 0;j < graph.length;j++) { cache[i][j] = -1; } } int[][] dist = calDist(graph); int ret = 0x3fffffff; for (int i = 0;i < graph.length;i++) { ret = Math.min(ret, solve((1 << i), i, dist, cache)); } return ret; } } ```
上一篇:
猜词游戏
下一篇:
矩形区域II
该分类下的相关小册推荐:
编程之道-算法面试(下)
数据结构与算法之美
算法面试通关 50 讲
数据结构与算法(下)
编程之道-算法面试(上)
数据结构与算法(上)
业务开发实用算法精讲