算法题解之贪心法

Wiggle Subsequence

最长扭动子序列

思路1:动态规划。状态dp[i]表示以nums[i]为末尾的最长wiggle子序列的长度。时间是O(n^2).

 1 public class Solution {
 2     public int wiggleMaxLength(int[] nums) {
 3         if (nums == null || nums.length == 0) {
 4             return 0;
 5         }
 6         int[] pos_dp = new int[nums.length];
 7         int[] neg_dp = new int[nums.length];
 8
 9         pos_dp[0] = 1;
10         neg_dp[0] = 1;
11         for (int i = 1; i < pos_dp.length; i++) {
12             neg_dp[i] = 1;
13             pos_dp[i] = 1;
14             for (int j = 0; j < i; j++) {
15                 if (nums[j] > nums[i]) {
16                     neg_dp[i] = Math.max(neg_dp[i], pos_dp[j] + 1);
17                 } else if (nums[j] < nums[i]) {
18                     pos_dp[i] = Math.max(pos_dp[i], neg_dp[j] + 1);
19                 }
20             }
21         }
22
23         int res = 0;
24         for (int i = 0; i < pos_dp.length; i++) {
25             res = Math.max(Math.max(pos_dp[i], neg_dp[i]), res);
26         }
27         return res;
28     }
29 }

思路2:贪心法。把数组看作一个波浪形,则由起点,终点,波峰,波谷构成的序列就是最长扭动子序列。时间是O(n),空间是O(1)。

 1 public class Solution {
 2     public int wiggleMaxLength(int[] nums) {
 3         if (nums == null || nums.length == 0) {
 4             return 0;
 5         }
 6
 7         int j = 0;
 8         while (j < nums.length - 1 && nums[0] == nums[++j]) {}
 9         if (j == nums.length - 1 && nums[j] == nums[0]) {
10             return 1;
11         }
12
13         int res = 2;
14         boolean up = nums[j] > nums[0];
15         for (int i = j + 1; i < nums.length; i++) {
16             if ((up && nums[i] < nums[i - 1]) || (!up && nums[i] > nums[i - 1])) {
17                 res++;
18                 up = !up;
19             }
20         }
21         return res;
22     }
23 }

时间: 2024-10-25 05:21:06

算法题解之贪心法的相关文章

算法学习笔记——贪心法

一.基本概念 所谓贪心算法是指,在对问题求解时,总是做出在当前看来是最好的选择.也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解. 贪心算法没有固定的算法框架,算法设计的关键是贪心策略的选择.必须注意的是,贪心算法不是对所有问题都能得到整体最优解,选择的贪心策略必须具备无后效性,即某个状态以后的过程不会影响以前的状态,只与当前状态有关.所以对所采用的贪心策略一定要仔细分析其是否满足无后效性. 二.贪心算法的基本思路 1.建立数学模型来描述问题 2.把求解的问题分成若干个子

贪心法 codevs 1052 地鼠游戏

1052 地鼠游戏 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 题目描述 Description 王钢是一名学习成绩优异的学生,在平时的学习中,他总能利用一切时间认真高效地学习,他不但学习刻苦,而且善于经常总结.完善自己的学习方法,所以他总能在每次考试中得到优异的分数,这一切很大程度上是由于他是一个追求效率的人. 但王钢也是一个喜欢玩的人,平时在学校学习他努力克制自己玩,可在星期天他却会抽一定的时间让自己玩一下,他的爸爸妈妈也比较信任他的学习能力

贪心法

贪心法(Greedy Approach)又称贪婪法, 在对问题求解时,总是做出在当前看来是最好的选择,或者说是:总是作出在当前看来最好的选择.也就是说贪心算法并不从整体最优考虑,它所作出的选择只是在某种意义上的局部最优选择.当然,希望贪心算法得到的最终结果也是整体最优的.虽然贪心算法不能对所有问题都得到整体最优解,但对许多问题它能产生整体最优解.如单源最短路经问题,最小生成树问题等.在一些情况下,即使贪心算法不能得到整体最优解,其最终结果却是最优解的很好近似. 贪心法的设计思想 当一个问题具有以

8.4 贪心法

1.背包问题: ①最优装载问题:把物体重量从小到大排列,依次选择每个物体,只顾眼前,却能得到最优解. ②部分背包问题:把物体的"价值除以重量的值"从小到大排序,一次选择每个物体(贪心只能对一个变量贪心,这是一种巧妙的转换). ③乘船问题:只让眼前的浪费最少.(注意是让什么最少,是让浪费最少!) 2.区间相关问题(排序:排左边还是右边?): ①选择不相交区间: ②区间选点问题: ③区间覆盖问题: 3.定义: 在对问题求解时,总是做出在当前看来是最好的选择.也就是说,不从整体最优上加以考虑

POJ 3259 Wormholes SPFA算法题解

本题其实也可以使用SPFA算法来求解的,不过就一个关键点,就是当某个顶点入列的次数超过所有顶点的总数的时候,就可以判断是有负环出现了. SPFA原来也是可以处理负环的. 不过SPFA这种处理负环的方法自然比一般的Bellman Ford算法要慢点了. #include <stdio.h> #include <string.h> #include <limits.h> const int MAX_N = 501; const int MAX_M = 2501; const

POJ 3461 Oulipo KMP算法题解

本题就是给出很多对字符串,然后问一个字符串在另外一个字符串出现的次数. 就是所谓的Strstr函数啦. Leetcode有这道几乎一模一样的题目. 使用KMP算法加速,算法高手必会的算法了. 另外看见讨论说什么使用KMP还超时,最大可能是没有真正理解next table的含义,写了错误的代码,故此虽然自己运行结果正确,但是却没有真正发挥next table的作用,使得算法退化为暴力法了,所以运行正确,但超时. KMP参考: http://blog.csdn.net/kenden23/articl

[LeetCode]wildcard matching通配符实现之贪心法

前天用递归LTE,昨天用动态规划LTE,今天接着搞,改用贪心法.题目再放一次: '?'匹配任意字符,'*'匹配任意长度字符串 Some examples: isMatch("aa","a") → false isMatch("aa","aa") → true isMatch("aaa","aa") → false isMatch("aa", "*"

POJ 2560 Freckles Prime算法题解

本题是求最小生成树. 给出的是坐标节点,然后需要根据这些坐标计算出各个点之间的距离. 除此就是标准的Prime算法了,能使用Prime的基本上都可以使用Kruskal. 这些经典的算法一定要多写,熟练掌握,否则很难灵活运用的. 而且经典的算法之所以为经典,原因之一是没那么容易自己凭空想象出来的,所以要熟练. #include <stdio.h> #include <string.h> #include <queue> #include <float.h> #

C语言(贪心法)

C语言有这样一个规则,每一个符号应该包含尽可能多的字符.也就是说,编译器将程序分解成符号的方法是,从左到右一个一个字符地读入,如果字条可能组成一个符号,那么再读入下一个字符,判断已经读入的两个字符组成的字符串是否可能是一个符号的组成部分,如果可能,继续读入下一个字条,重复上述判断,直到读入的字符组成的字符串已经不再可能组成一个有意义的符号.这个处理的策略被称为"贪心法".需要注意的是,除了字符串与字符常量,符号的中间不能嵌有空白(空格.制表符.换行符等). 看一下下面的代码:想一下输出