当前位置: 首页 > wzjs >正文

网站怎么做电脑系统下载文件如何做网站推广广告

网站怎么做电脑系统下载文件,如何做网站推广广告,网站二维码收费怎么做,织梦建公司网站题目描述 给定一个长度为 n 的下标从 0 开始的整数数组 nums。初始位置为下标 0。当 i < j 时&#xff0c;你可以从下标 i 跳转到下标 j: 对于在 i < k < j 范围内的所有下标 k 有 nums[i] < nums[j] 和 nums[k] < nums[i] , 或者对于在 i < k < j 范围…

题目描述

给定一个长度为 n 的下标从 0 开始的整数数组 nums。初始位置为下标 0。当 i < j 时,你可以从下标 i 跳转到下标 j:

  • 对于在 i < k < j 范围内的所有下标 k 有 nums[i] <= nums[j] 和 nums[k] < nums[i] , 或者
  • 对于在 i < k < j 范围内的所有下标 k 有 nums[i] > nums[j] 和 nums[k] >= nums[i] 。

你还得到了一个长度为 n 的整数数组 costs,其中 costs[i] 表示跳转下标 i 的代价。

返回跳转到下标 n - 1 的最小代价。

示例 1:

输入: nums = [3,2,4,4,1], costs = [3,7,6,4,2]
输出: 8
解释: 从下标 0 开始。
- 以 costs[2]= 6 的代价跳转到下标 2。
- 以 costs[4]= 2 的代价跳转到下标 4。
总代价是 8。可以证明,8 是所需的最小代价。
另外两个可能的路径是:下标 0 -> 1 -> 4 和下标 0 -> 2 -> 3 -> 4。
它们的总代价分别为9和12。

示例 2:

输入: nums = [0,1,2], costs = [1,1,1]
输出: 2
解释: 从下标 0 开始。
- 以 costs[1] = 1 的代价跳转到下标 1。
- 以 costs[2] = 1 的代价跳转到下标 2。
总代价是 2。注意您不能直接从下标 0 跳转到下标 2,因为 nums[0] <= nums[1]。

解释:

  • n == nums.length == costs.length
  • 1 <= n <= 10^5
  • 0 <= nums[i], costs[i] <= 10^5

问题分析

这道题是跳跃游戏系列中的一道具有挑战性的题目。关键在于理解跳跃条件:

跳跃条件解析:

  • 条件一: nums[i] <= nums[j] 且中间所有 nums[k] < nums[i]

    • 含义:从位置i跳到右侧第一个 ≥ nums[i] 的位置

    • 对应:单调递减栈(维护一个从栈底到栈顶递减的序列)

  • 条件二: nums[i] > nums[j] 且中间所有 nums[k] >= nums[i]

    • 含义:从位置i跳到右侧第一个 < nums[i] 的位置

    • 对应:单调递增栈(维护一个从栈底到栈顶递增的序列)

这两个条件实际上是互补的,可以用单调栈来高效处理。


解题思路

单调栈 + 动态规划

核心思想:

  1. 使用两个单调栈分别处理两种跳跃条件
  2. 用动态规划记录到达每个位置的最小代价
  3. 从左到右遍历,动态更新可达位置的最小代价

算法步骤:

  • 初始化 dp[i] 表示到达位置 i 的最小代价,dp[0] = 0
  • 维护两个单调栈:
    • stack1:处理条件一(单调递减栈)
    • stack2:处理条件二(单调递增栈)
  • 对每个位置 j,检查能从哪些位置跳到 j,并更新最小代价

算法过程

输入: nums = [3,2,4,4,1], costs = [3,7,6,4,2]

初始状态

位置:    0  1  2  3  4
nums:   [3, 2, 4, 4, 1]
costs:  [3, 7, 6, 4, 2]
dp:     [0, ∞, ∞, ∞, ∞]stack1: []  (单调递减栈 - 处理条件一)
stack2: []  (单调递增栈 - 处理条件二)

步骤1:处理位置0 (nums[0] = 3)

当前位置 j = 0, nums[0] = 3stack1操作:
- 栈为空,直接入栈
- stack1: [0]stack2操作:
- 栈为空,直接入栈  
- stack2: [0]dp状态:[0, ∞, ∞, ∞, ∞]

步骤2:处理位置1 (nums[1] = 2)

当前位置 j = 1, nums[1] = 2stack1操作(条件一):
- nums[stack1.top()] = nums[0] = 3 > nums[1] = 2
- 不满足 nums[i] <= nums[j],不弹出
- stack1: [0, 1]stack2操作(条件二):
- nums[stack2.top()] = nums[0] = 3 > nums[1] = 2 ✓
- 弹出位置0,更新 dp[1] = min(∞, dp[0] + costs[1]) = min(∞, 0 + 7) = 7
- 将位置1入栈
- stack2: [1]dp状态:[0, 7, ∞, ∞, ∞]跳跃路径:0 → 1 (代价7)

步骤3:处理位置2 (nums[2] = 4)

当前位置 j = 2, nums[2] = 4stack1操作(条件一):
- nums[1] = 2 <= nums[2] = 4 ✓,弹出位置1dp[2] = min(∞, dp[1] + costs[2]) = min(∞, 7 + 6) = 13
- nums[0] = 3 <= nums[2] = 4 ✓,弹出位置0  dp[2] = min(13, dp[0] + costs[2]) = min(13, 0 + 6) = 6
- 将位置2入栈
- stack1: [2]stack2操作(条件二):
- nums[1] = 2 < nums[2] = 4,不满足条件二,不弹出
- 将位置2入栈
- stack2: [1, 2]dp状态:[0, 7, 6, ∞, ∞]跳跃路径:0 → 2 (代价6) 或 0 → 1 → 2 (代价13)
最优:0 → 2 (代价6)

步骤4:处理位置3 (nums[3] = 4)

当前位置 j = 3, nums[3] = 4stack1操作(条件一):
- nums[2] = 4 <= nums[3] = 4 ✓,弹出位置2dp[3] = min(∞, dp[2] + costs[3]) = min(∞, 6 + 4) = 10
- 将位置3入栈
- stack1: [3]stack2操作(条件二):
- nums[2] = 4 不大于 nums[3] = 4,不弹出
- 将位置3入栈
- stack2: [1, 2, 3]dp状态:[0, 7, 6, 10, ∞]跳跃路径:0 → 2 → 3 (代价10)

步骤5:处理位置4 (nums[4] = 1)

当前位置 j = 4, nums[4] = 1stack1操作(条件一):
- nums[3] = 4 > nums[4] = 1,不满足条件一,不弹出
- 将位置4入栈
- stack1: [3, 4]stack2操作(条件二):
- nums[3] = 4 > nums[4] = 1 ✓,弹出位置3dp[4] = min(∞, dp[3] + costs[4]) = min(∞, 10 + 2) = 12
- nums[2] = 4 > nums[4] = 1 ✓,弹出位置2dp[4] = min(12, dp[2] + costs[4]) = min(12, 6 + 2) = 8
- nums[1] = 2 > nums[4] = 1 ✓,弹出位置1dp[4] = min(8, dp[1] + costs[4]) = min(8, 7 + 2) = 9
- 最终 dp[4] = 8
- stack2: [4]dp状态:[0, 7, 6, 10, 8]跳跃路径:0 → 2 → 4 (代价8)

最优路径

最终答案:dp[4] = 8最优路径:0 → 2 → 4
详细分析:
- 从位置0跳到位置2:满足条件一 (nums[0]=3 <= nums[2]=4,中间nums[1]=2 < nums[0]=3)
- 从位置2跳到位置4:满足条件二 (nums[2]=4 > nums[4]=1,中间nums[3]=4 >= nums[2]=4)
- 总代价:costs[2] + costs[4] = 6 + 2 = 8

详细代码实现

Java 实现

class Solution {public long minCost(int[] nums, int[] costs) {int n = nums.length;long[] dp = new long[n];// 初始化dp数组Arrays.fill(dp, Long.MAX_VALUE);dp[0] = 0;  // 起始位置代价为0// 两个单调栈Deque<Integer> stack1 = new ArrayDeque<>();  // 处理条件一Deque<Integer> stack2 = new ArrayDeque<>();  // 处理条件二for (int j = 0; j < n; j++) {// 处理条件一:nums[i] <= nums[j] 且中间元素都小于 nums[i]// 单调递减栈,当遇到更大的元素时弹出while (!stack1.isEmpty() && nums[stack1.peek()] <= nums[j]) {int i = stack1.pop();dp[j] = Math.min(dp[j], dp[i] + costs[j]);}stack1.push(j);// 处理条件二:nums[i] > nums[j] 且中间元素都大于等于 nums[i]// 单调递增栈,当遇到更小的元素时弹出while (!stack2.isEmpty() && nums[stack2.peek()] > nums[j]) {int i = stack2.pop();dp[j] = Math.min(dp[j], dp[i] + costs[j]);}stack2.push(j);}return dp[n - 1];}
}

C# 实现

public class Solution {public long MinCost(int[] nums, int[] costs) {int n = nums.Length;long[] dp = new long[n];// 初始化dp数组for (int i = 0; i < n; i++) {dp[i] = long.MaxValue;}dp[0] = 0;  // 起始位置代价为0// 两个单调栈Stack<int> stack1 = new Stack<int>();  // 处理条件一Stack<int> stack2 = new Stack<int>();  // 处理条件二for (int j = 0; j < n; j++) {// 处理条件一:nums[i] <= nums[j] 且中间元素都小于 nums[i]while (stack1.Count > 0 && nums[stack1.Peek()] <= nums[j]) {int i = stack1.Pop();dp[j] = Math.Min(dp[j], dp[i] + costs[j]);}stack1.Push(j);// 处理条件二:nums[i] > nums[j] 且中间元素都大于等于 nums[i]while (stack2.Count > 0 && nums[stack2.Peek()] > nums[j]) {int i = stack2.Pop();dp[j] = Math.Min(dp[j], dp[i] + costs[j]);}stack2.Push(j);}return dp[n - 1];}
}

时间复杂度和空间复杂度

  • 时间复杂度:O(n) - 每个元素最多入栈和出栈一次
  • 空间复杂度:O(n) - dp数组和两个栈的空间
http://www.dtcms.com/wzjs/385460.html

相关文章:

  • 苹果软件开发南昌网站seo
  • 电脑网站建设网站外链工具
  • 怎样用php做网站seo网站优化推广
  • 怎么创建自己的网站平台app重庆森林经典台词梁朝伟
  • 网站建设报价多少烟台seo快速排名
  • 做兼职去哪个网站友情链接的作用有哪些
  • 做货运网站找哪家好网站seo优化总结
  • 受大众喜欢的域名备案加急淄博网站优化
  • 企业网站建设 新闻宣传如何制作一个简易网站
  • 做网站的结论与心得优化模型的推广
  • 返利网网站框架目录小程序排名优化
  • 优秀平面设计作品网站营销策划方案ppt
  • 网站建设策划书模板现代网络营销的方式
  • 多语种网站建设怎么做自己的网站
  • 南山建网站公司深圳网络推广
  • 自适应企业网站足球队世界排名榜
  • 旅游网站建设标书广东短视频seo搜索哪家好
  • 英文网站备案搜索引擎大全排名
  • 咸阳建设网站seo算法入门教程
  • 龙岗建设招标局网站市场调研流程
  • 中国网络公司360优化大师历史版本
  • 网络服务主要包括什么淮南网站seo
  • wordpress menu_walker关键词营销优化
  • 厦门网站制作建设网络推广加盟
  • 做 理财网站2021年经典营销案例
  • 学交互设计网站搜索引擎优化答案
  • 安装了lnmp怎么做网站seo技术培训班
  • nodejs 网站开发模块网页设计软件dreamweaver
  • 华夏名网修改网站信息深圳网站快速排名优化
  • wordpress外链图本地化青海seo关键词排名优化工具