栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

九章算法 贪心算法和动态规划-跳跃游戏 II 单词拆分(一)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

九章算法 贪心算法和动态规划-跳跃游戏 II 单词拆分(一)

算法基础源码获取 第一题:

描述

给出一个非负整数数组,你最初定位在数组的第一个位置。

数组中的每个元素代表你在那个位置可以跳跃的最大长度。

你的目标是使用最少的跳跃次数到达数组的最后一个位置。

数组A的长度不超过20000,每个元素的大小不超过20000

样例

样例 1:

输入:

A = [2,3,1,1,4]

输出:

2

解释:

到达最后位置的最小跳跃次数是2(从下标0到1跳跃1个距离长度,然后跳跃3个距离长度到最后位置)

解题思路

这道题是典型的贪心算法,通过局部最优解得到全局最优解。有两种方法使用贪心算法实现,只是贪心的策略不同。
目标是到达数组的最后一个位置,因此我们可以考虑最后一步跳跃前所在的位置,该位置通过跳跃能够到达最后一个位置。

如果有多个位置通过跳跃都能够到达最后一个位置,可以「贪心」地选择距离最后一个位置最远的那个位置,也就是对应下标最小的那个位置。因此,我们可以从左到右遍历数组,选择第一个满足要求的位置。

找到最后一步跳跃前所在的位置之后,继续贪心地寻找倒数第二步跳跃前所在的位置,以此类推,直到找到数组的开始位置。

使用这种方法编写的 C++ 和 Python 代码会超出时间限制。


题解代码

java

1public class Solution {
2    
6    public int jump(int[] a) {
7        // write your code here
8        int position = a.length - 1;
9        int steps = 0;
10        while (position > 0) {
11            for (int i = 0; i < position; i++) {
12                if (i + a[i] >= position) {
13                    position = i;
14                    steps++;
15                    break;
16                }
17            }
18        }
19        return steps;
20    }
21}

复杂度分析
  • 时间复杂度:O(n^2)O(n2),其中 nn 是数组长度。有两层嵌套循环,在最坏的情况下,例如数组中的所有元素都是 11,position 需要遍历数组中的每个位置,对于 position 的每个值都有一次循环。

  • 空间复杂度:O(1)O(1)。

第二题:

描述

给定字符串 s 和单词字典 dict,确定 s 是否可以分成一个或多个以空格分隔的子串,并且这些子串都在字典中存在。
因为我们已经使用了更强大的数据,所以普通的DFS方法无法解决此题。

样例

样例 1:

输入:

s = "lintcode"
dict = ["lint", "code"]

输出:

true

解释:

lintcode可以分成lint和code。

样例 2:

输入:

s = "a"
dict = ["a"]

输出:

true

解释:

a在dict中。

使用《九章算法班》中讲过的划分型动态规划算法

  • state: dp[i] 表示前 i 个字符是否能够被划分为若干个单词
  • function: dp[i] = or{dp[j] and j + 1~i 是一个单词}

java

1public class Solution {
2    
7    public boolean wordBreak(String s, Set dict) {
8        if (s == null) {
9            return true;
10        }
11        
12        int maxLength = 0;
13        for (String word : dict) {
14            maxLength = Math.max(maxLength, word.length());
15        }
16      
17        int n = s.length();
18        boolean[] dp = new boolean[n + 1];
19        dp[0] = true;
20        
21        for (int i = 1; i <= n; i++) {
22            for (int l = 1; l <= maxLength; l++) {
23                if (i < l) {
24                    break;
25                }
26                if (!dp[i - l]) {
27                    continue;
28                }
29                String word = s.substring(i - l, i);
30                if (dict.contains(word)) {
31                    dp[i] = true;
32                    break;
33                }
34            }
35        }
36        
37        return dp[n];
38    }
39}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/988178.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号