LeetCode精选TOP面试题(中等2)
Posted _light_house_
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode精选TOP面试题(中等2)相关的知识,希望对你有一定的参考价值。
文章目录
- [787. K 站中转内最便宜的航班](https://leetcode-cn.com/problems/cheapest-flights-within-k-stops/)
- [319. 灯泡开关](https://leetcode-cn.com/problems/bulb-switcher/)
- [743. 网络延迟时间](https://leetcode-cn.com/problems/network-delay-time/)
- [397. 整数替换](https://leetcode-cn.com/problems/integer-replacement/)
- [204. 计数质数](https://leetcode-cn.com/problems/count-primes/)
- [241. 为运算表达式设计优先级](https://leetcode-cn.com/problems/different-ways-to-add-parentheses/)
- [423. 从英文中重建数字](https://leetcode-cn.com/problems/reconstruct-original-digits-from-english/)
- [413. 等差数列划分](https://leetcode-cn.com/problems/arithmetic-slices/)
- [524. 通过删除字母匹配到字典里最长单词](https://leetcode-cn.com/problems/longest-word-in-dictionary-through-deleting/)
- [109. 有序链表转换二叉搜索树](https://leetcode-cn.com/problems/convert-sorted-list-to-binary-search-tree/)
- [406. 根据身高重建队列](https://leetcode-cn.com/problems/queue-reconstruction-by-height/)
- [375. 猜数字大小 II](https://leetcode-cn.com/problems/guess-number-higher-or-lower-ii/)
- [1583. 统计不开心的朋友](https://leetcode-cn.com/problems/count-unhappy-friends/)
- [384. 打乱数组](https://leetcode-cn.com/problems/shuffle-an-array/)
- [863. 二叉树中所有距离为 K 的结点](https://leetcode-cn.com/problems/all-nodes-distance-k-in-binary-tree/)
- [1818. 绝对差值和](https://leetcode-cn.com/problems/minimum-absolute-sum-difference/)
- [1711. 大餐计数](https://leetcode-cn.com/problems/count-good-meals/)
- [981. 基于时间的键值存储](https://leetcode-cn.com/problems/time-based-key-value-store/)
- [313. 超级丑数](https://leetcode-cn.com/problems/super-ugly-number/)
- [395. 至少有 K 个重复字符的最长子串](https://leetcode-cn.com/problems/longest-substring-with-at-least-k-repeating-characters/)
- [400. 第 N 位数字](https://leetcode-cn.com/problems/nth-digit/)
- [670. 最大交换](https://leetcode-cn.com/problems/maximum-swap/)
- [1418. 点菜展示表](https://leetcode-cn.com/problems/display-table-of-food-orders-in-a-restaurant/)
- [528. 按权重随机选择](https://leetcode-cn.com/problems/random-pick-with-weight/)
- [725. 分隔链表](https://leetcode-cn.com/problems/split-linked-list-in-parts/)
- [318. 最大单词长度乘积](https://leetcode-cn.com/problems/maximum-product-of-word-lengths/)
- [386. 字典序排数](https://leetcode-cn.com/problems/lexicographical-numbers/)
- [802. 找到最终的安全状态](https://leetcode-cn.com/problems/find-eventual-safe-states/)
- [1109. 航班预订统计](https://leetcode-cn.com/problems/corporate-flight-bookings/)
- [838. 推多米诺](https://leetcode-cn.com/problems/push-dominoes/)
- [299. 猜数字游戏](https://leetcode-cn.com/problems/bulls-and-cows/)
- [89. 格雷编码](https://leetcode-cn.com/problems/gray-code/)
- [904. 水果成篮](https://leetcode-cn.com/problems/fruit-into-baskets/)
- [519. 随机翻转矩阵](https://leetcode-cn.com/problems/random-flip-matrix/)
- [638. 大礼包](https://leetcode-cn.com/problems/shopping-offers/)
- [1743. 从相邻元素对还原数组](https://leetcode-cn.com/problems/restore-the-array-from-adjacent-pairs/)
- [38. 外观数列](https://leetcode-cn.com/problems/count-and-say/)
- [789. 逃脱阻碍者](https://leetcode-cn.com/problems/escape-the-ghosts/)
- [300. 最长递增子序列](https://leetcode-cn.com/problems/longest-increasing-subsequence/)
- [334. 递增的三元子序列](https://leetcode-cn.com/problems/increasing-triplet-subsequence/)
- [650. 只有两个键的键盘](https://leetcode-cn.com/problems/2-keys-keyboard/)
- [797. 所有可能的路径](https://leetcode-cn.com/problems/all-paths-from-source-to-target/)
- [654. 最大二叉树](https://leetcode-cn.com/problems/maximum-binary-tree/)
- [86. 分隔链表](https://leetcode-cn.com/problems/partition-list/)
- [457. 环形数组是否存在循环](https://leetcode-cn.com/problems/circular-array-loop/)
- [713. 乘积小于K的子数组](https://leetcode-cn.com/problems/subarray-product-less-than-k/)
- [447. 回旋镖的数量](https://leetcode-cn.com/problems/number-of-boomerangs/)
- [662. 二叉树最大宽度](https://leetcode-cn.com/problems/maximum-width-of-binary-tree/)
787. K 站中转内最便宜的航班
(bellman-ford最短路)
本题是一个用限制条件的最短路径问题,我们可以使用bellman-ford算法直接计算即可。
本质上bellman-ford算法就是一个dp。
dp[k][i]
表示从起点
出发最多经过k
条边走到i
中所有路径中长度的最小值。
所以f[k][i] = minf[k - 1][j] + dist[j]
。
class Solution
static int INF = 0x3f3f3f3f;
public int findCheapestPrice(int n, int[][] flights, int src, int dst, int k)
int[][] f = new int[k + 2][n];
for (int i = 0; i < k + 2; i ++)
Arrays.fill(f[i], INF);
f[0][src] = 0;
int ans = INF;
for (int t = 1; t <= k + 1; t ++)
for (int[] flight : flights)
int from = flight[0], to = flight[1], w = flight[2];
f[t][to] = Math.min(f[t][to], f[t - 1][from] + w);
for (int t = 1; t <= k + 1; t ++)
ans = Math.min(ans, f[t][dst]);
return ans == INF ? -1 : ans;
(bellman-ford最短路-空间优化)
因为每一次只用到二维数组中的上一层中的数字,所以我们可以使用两个一维数组滚动的使用。
class Solution
public int findCheapestPrice(int n, int[][] flights, int src, int dst, int k)
int INF = 0x3f3f3f3f;
int[] dist = new int[n];
Arrays.fill(dist, INF);
dist[src] = 0;
// k个中间点,k+1条边,k+1次循环
for (int i = 0; i <= k; i ++)
// 用cur表示临时数组
int[] cur = new int[n];
cur = Arrays.copyOf(dist, n);
// 上面两句可以使用int[] cur = dist.clone();替代
for (int[] f : flights)
int from = f[0], to = f[1], w = f[2];
cur[to] = Math.min(cur[to], dist[from] + w);
dist = cur;
if (dist[dst] == INF) return -1;
else return dist[dst];
Java的完整写法
class Solution
class Edge
int x, y, w;
Edge(int _x, int _y, int _w)
x = _x; y = _y; w = _w;
int N = 110, INF = 0x3f3f3f3f;
// n个点,m条边,k步之内,从src到dst
int n, m, k, src, dst;
List<Edge> list = new ArrayList<>();
int[] dist = new int[N];
public int findCheapestPrice(int _n, int[][] flights, int _src, int _dst, int _k)
n = _n; src = _src; dst = _dst; k = _k + 1;
for (int[] f : flights)
list.add(new Edge(f[0], f[1], f[2]));
m = list.size();
int ans = bellman_ford();
return ans > INF / 2 ? -1 : ans;
public int bellman_ford()
Arrays.fill(dist, INF);
dist[src] = 0;
for (int i = 0; i < k; i ++)
int[] cur = dist.clone();
for (Edge e : list)
int x = e.x, y = e.y, w = e.w;
dist[y] = Math.min(dist[y], cur[x] + w);
return dist[dst];
319. 灯泡开关
(数学+脑筋急转弯)
如果一个灯泡最后是亮的,说明它被摁了偶数次。如果灯泡最后是灭的,说明它被摁了奇数次。而一个灯泡被摁的次数和n
的约数个数有关。如果一个数字是完全平方数说明它的约数个数为奇数。如果一个数字不是完全平方数,说明它的约数个数一定是偶数。所以我们只要看1~n
中有多少的完全平方数即可。即sqrt(n)
。
class Solution
public int bulbSwitch(int n)
return (int)Math.sqrt(n);
743. 网络延迟时间
我们要知道多久才可以使得所有的点都可以接收到信号。其实就是在求从k
出发到达所有点的最短路中,哪一个最短路需要的时间最多。(因为如果最大的最短路所用的时间一定可以到达其他所有的点)。
所以本题主要考察我们最短路的图论模板怎么写,有5种方式的图论最短路朴素版Dijkstra
,堆优化版Dijkstra
,bellman-ford
,spfa
和floyd
最短路。
(朴素版Dijkstra最短路)
每一次确定一个离源点最近的点,然后用这个点去优化从这个出发的路径。
class Solution
final int INF = 0x3f3f3f3f;
public int networkDelayTime(int[][] times, int n, int k)
int[][] g = new int[n + 1][n + 1];
for (int i = 1; i <= n; i ++)
Arrays.fill(g[i], INF);
for (int[] time : times)
int a = time[0], b = time[1], w = time[2];
g[a][b] = w;
int[] dist = new int[n + 1];
Arrays.fill(dist, INF);
dist[k] = 0;
boolean[] vis = new boolean[n + 1];
for (int i = 1; i <= n; i ++)
int x = -1;
for (int y = 1; y <= n; y ++)
if (!vis[y] && (x == -1 || dist[x] > dist[y]))
x = y;
vis[x] = true;
for (int j = 1; j <= n; j ++)
dist[j] = Math.min(dist[j], dist[x] + g[x][j]);
int ans = 0;
for (int i = 1; i <= n; i ++)
ans = Math.max(ans, dist[i]);
return ans > INF / 2 ? -1 : ans;
(堆优化版Dijkstra最短路)
我们可以使用堆的结构优化上面使用循环找到离源点最近的一个点的位置。使用priority_queue
,并且存放从该点到源点的距离, 该点的编号
,就可以在O(1)的时间内找到距离源点最近的点。
class Solution
final int N = 110, M = 6010;
int INF = 0x3f3f3f3f;
int[] he = new int[N], e = new int[M], w = new int[M], ne = new int[M];
int idx = 0;
void add(int a, int b, int c)
e[idx] = b;
w[idx] = c;
ne[idx] = he[a];
he[a] = idx;
idx ++;
boolean[] vis = new boolean[N];
int[] dist = new int[N];
int n, k;
public int networkDelayTime(int[][] times, int _n, int _k)
n = _n; k = _k;
Arrays.fill(he, -1);
Arrays.fill(dist, INF);
for (int[] time : times)
int a = time[0], b = time[1], c = time[2];
add(a, b, c);
dijkstra();
int ans = 0;
for (int i = 1; i <= n; i ++)
ans = Math.max(ans, dist[i]);
return ans > INF / 2 ? -1 : ans;
void dijkstra()
dist[k] = 0;
PriorityQueue<int[]> q = new PriorityQueue<>((a, b)->a[0]-b[0]);
q.add(new int[]0, k);
while (!q.isEmpty())
int[] top = q.poll();
int ver = top[1], distance = top[0以上是关于LeetCode精选TOP面试题(中等2)的主要内容,如果未能解决你的问题,请参考以下文章
图解精选 TOP 面试题 001 | LeetCode 237. 删除链表中的节点
leetcode 最常见的 150 道前端面试题(简单题上)
⭐算法入门⭐《二分枚举》中等02 —— LeetCode 面试题 10.09. 排序矩阵查找