软考-算法-下
单调栈
739. 每日温度
给定一个整数数组
temperatures,表示每天的温度,返回一个数组answer,其中answer[i]是指对于第i天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位置用0来代替。示例 1:
1
2 输入: temperatures = [73,74,75,71,69,72,76,73]
输出: [1,1,4,2,1,1,0,0]示例 2:
1
2 输入: temperatures = [30,40,50,60]
输出: [1,1,1,0]示例 3:
1
2 输入: temperatures = [30,60,90]
输出: [1,1,0]
1 | // 从右往左 |
步骤图解
用
temperatures = [73,74,75,71,69,72,76,73]来模拟:
i (从右向左) t 栈中下标(温度) 比较与弹出 操作后 ans[i] 入栈后状态 7 (73) 73 空 - 0 [7(73)]6 (76) 76 [7(73)]76 >= 73,弹出7 0 [6(76)]5 (72) 72 [6(76)]72 >= 76? 否 6-5 = 1[6(76), 5(72)]4 (69) 69 [6(76), 5(72)]69 >= 72? 否 5-4 = 1[6(76), 5(72), 4(69)]3 (71) 71 [..., 4(69)]71 >= 69? 是,弹出4。现在栈顶是5(72),71 >= 72? 否 5-3 = 2[6(76), 5(72), 3(71)]2 (75) 75 [..., 3(71)]75 >= 71? 是,弹出3。栈顶5(72),75 >= 72? 是,弹出5。栈顶6(76),75 >= 76? 否 6-2 = 4[6(76), 2(75)]1 (74) 74 [6(76), 2(75)]74 >= 75? 否 2-1 = 1[6(76), 2(75), 1(74)]0 (73) 73 [..., 1(74)]73 >= 74? 否 1-0 = 1[6(76), 2(75), 1(74), 0(73)]现在结果是
[1, 1, 4, 2, 1, 1, 0, 0],与示例完全一致。
496. 下一个更大元素 I
nums1中数字x的 下一个更大元素 是指x在nums2中对应位置 右侧 的 第一个 比x大的元素。给你两个 没有重复元素 的数组
nums1和nums2,下标从 0 开始计数,其中nums1是nums2的子集。对于每个
0 <= i < nums1.length,找出满足nums1[i] == nums2[j]的下标j,并且在nums2确定nums2[j]的 下一个更大元素 。如果不存在下一个更大元素,那么本次查询的答案是-1。返回一个长度为
nums1.length的数组ans作为答案,满足ans[i]是如上所述的 下一个更大元素 。示例 1:
1
2
3
4
5
6 输入:nums1 = [4,1,2], nums2 = [1,3,4,2].
输出:[-1,3,-1]
解释:nums1 中每个值的下一个更大元素如下所述:
- 4 ,用加粗斜体标识,nums2 = [1,3,4,2]。不存在下一个更大元素,所以答案是 -1 。
- 1 ,用加粗斜体标识,nums2 = [1,3,4,2]。下一个更大元素是 3 。
- 2 ,用加粗斜体标识,nums2 = [1,3,4,2]。不存在下一个更大元素,所以答案是 -1 。示例 2:
1
2
3
4
5 输入:nums1 = [2,4], nums2 = [1,2,3,4].
输出:[3,-1]
解释:nums1 中每个值的下一个更大元素如下所述:
- 2 ,用加粗斜体标识,nums2 = [1,2,3,4]。下一个更大元素是 3 。
- 4 ,用加粗斜体标识,nums2 = [1,2,3,4]。不存在下一个更大元素,所以答案是 -1 。
1 | class Solution { |
步骤图解
为了更直观,我们用
nums1 = [4,1,2],nums2 = [1,3,4,2]来模拟过程:
步骤 i x 栈操作 x 在 nums1 中? 动作 1 3 2 栈空,入栈 → [2]✅ 是 栈空,不记录 2 2 4 4 >= 2,弹出 2 → 栈空,入栈 →[4]✅ 是 栈空,不记录 3 1 3 3 >= 4? 否,入栈 →[4, 3]❌ 否 不记录 4 0 1 1 >= 3? 否,入栈 →[4, 3, 1]✅ 是 栈顶 3 存在,记录 ans[1] = 3最终
ans = [-1, 3, -1]✅(正确)
503. 下一个更大元素 II
给定一个循环数组
nums(nums[nums.length - 1]的下一个元素是nums[0]),返回nums中每个元素的 下一个更大元素 。数字
x的 下一个更大的元素 是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它的下一个更大的数。如果不存在,则输出-1。示例 1:
1
2
3
4
5 输入: nums = [1,2,1]
输出: [2,-1,2]
解释: 第一个 1 的下一个更大的数是 2;
数字 2 找不到下一个更大的数;
第二个 1 的下一个最大的数需要循环搜索,结果也是 2。示例 2:
1
2 输入: nums = [1,2,3,4,3]
输出: [2,3,4,-1,4]
1 | class Solution { |
步骤图解
i (从右向左) x = nums[i%3] 栈中元素(值) 比较与弹出 是否记录答案 操作后 ans[i%3] 入栈后状态 5 nums[2] = 1 空 - ❌ (i≥n) - [1]4 nums[1] = 2 [1]2 >= 1? 是,弹出1 ❌ (i≥n) - [2]3 nums[0] = 1 [2]1 >= 2? 否 ❌ (i≥n) - [2, 1]2 nums[2] = 1 [2, 1]1 >= 1? 是,弹出1;现在栈顶2,1 >= 2? 否 ✅ (i<n) ans[2] = 2 [2, 1]1 nums[1] = 2 [2, 1]2 >= 1? 是,弹出1;现在栈顶2,2 >= 2? 是,弹出2;栈空 ✅ (i<n) ans[1] = -1(栈空) [2]0 nums[0] = 1 [2]1 >= 2? 否 ✅ (i<n) ans[0] = 2 [2, 1]
难题暂缓
图论
图论统一使用ACM模式,ACM模式需要接收输入参数
本文只是用邻接矩阵的写法
可达路径
题目描述
给定一个有 n 个节点的有向无环图,节点编号从 1 到 n。请编写一个函数,找出并返回所有从节点 1 到节点 n 的路径。每条路径应以节点编号的列表形式表示。
输入描述
第一行包含两个整数 N,M,表示图中拥有 N 个节点,M 条边
后续 M 行,每行包含两个整数 s 和 t,表示图中的 s 节点与 t 节点中有一条路径
输出描述
输出所有的可达路径,路径中所有节点之间空格隔开,每条路径独占一行,存在多条路径,路径输出的顺序可任意。如果不存在任何一条路径,则输出 -1。
注意输出的序列中,最后一个节点后面没有空格! 例如正确的答案是
1 3 5,而不是1 3 5, 5后面没有空格!输入示例
1
2
3
4
5
6 5 5
1 3
3 5
1 2
2 4
4 5输出示例
1
2 1 3 5
1 2 4 5提示信息
用例解释:
有五个节点,其中的从 1 到达 5 的路径有两个,分别是 1 -> 3 -> 5 和 1 -> 2 -> 4 -> 5。
因为拥有多条路径,所以输出结果为:
1 3 5
1 2 4 5或
1 2 4 5
1 3 5
都算正确。数据范围:
- 图中不存在自环
- 图中不存在平行边
- 1 <= N <= 100
- 1 <= M <= 500
1 | import java.util.ArrayList; |
其他
不涉及到之前列出的其他方法,属于新思路
134. 加油站
在一条环路上有
n个加油站,其中第i个加油站有汽油gas[i]升。你有一辆油箱容量无限的的汽车,从第
i个加油站开往第i+1个加油站需要消耗汽油cost[i]升。你从其中的一个加油站出发,开始时油箱为空。给定两个整数数组
gas和cost,如果你可以按顺序绕环路行驶一周,则返回出发时加油站的编号,否则返回-1。如果存在解,则 保证 它是 唯一 的。示例 1:
1
2
3
4
5
6
7
8
9
10 输入: gas = [1,2,3,4,5], cost = [3,4,5,1,2]
输出: 3
解释:
从 3 号加油站(索引为 3 处)出发,可获得 4 升汽油。此时油箱有 = 0 + 4 = 4 升汽油
开往 4 号加油站,此时油箱有 4 - 1 + 5 = 8 升汽油
开往 0 号加油站,此时油箱有 8 - 2 + 1 = 7 升汽油
开往 1 号加油站,此时油箱有 7 - 3 + 2 = 6 升汽油
开往 2 号加油站,此时油箱有 6 - 4 + 3 = 5 升汽油
开往 3 号加油站,你需要消耗 5 升汽油,正好足够你返回到 3 号加油站。
因此,3 可为起始索引。示例 2:
1
2
3
4
5
6
7
8
9 输入: gas = [2,3,4], cost = [3,4,3]
输出: -1
解释:
你不能从 0 号或 1 号加油站出发,因为没有足够的汽油可以让你行驶到下一个加油站。
我们从 2 号加油站出发,可以获得 4 升汽油。 此时油箱有 = 0 + 4 = 4 升汽油
开往 0 号加油站,此时油箱有 4 - 3 + 2 = 3 升汽油
开往 1 号加油站,此时油箱有 3 - 3 + 3 = 3 升汽油
你无法返回 2 号加油站,因为返程需要消耗 4 升汽油,但是你的油箱只有 3 升汽油。
因此,无论怎样,你都不可能绕环路行驶一周。
1 | class Solution { |

