贪心算法
定义
由局部最优解得出的全局最优解
经典贪心
给一个由字符串组成的数组strs,把所有的字符拼接起来,返回所有可能的拼接结果中,字典序最小的结果
第一种贪心的思路是直接将字符数组按照字典序排序,并拼接,但是会发现这种策略是错误的,当出现数组中有dcb,d这种情况时,显然ddcb比dcbd字典序要大
由于第一种贪心思路的问题,我们找出了第二种贪心策略,即比较的时候用ddcb和dcbd来比较,这样子就处理了上面产生的问题
代码
public String concatStr(String [] strs){
Arrays.sort(strs,(obj1,obj2)-> (obj1+obj2).compareTo(obj2+obj1));
return Arrays.stream(strs).reduce((x1,x2)-> x1 + x2).get();
}
贪心的解题方式多变,只有通过多做题目来提升,下面是一道leetcode上的原题,让我们练习一下
题目
给定一个非负整数数组,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
你的目标是使用最少的跳跃次数到达数组的最后一个位置。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/jump-game-ii
贪心策略
第一个想法是当我位于i点时,去取i后面的n个数,此时
n
=
n
u
m
s
[
i
]
n=nums[i]
n=nums[i](nums为非负整数数组),取出中间最大的,向后跳跃,但是很快就否定了这一想法,因为对于数组[3,3,2,2,4,5,1,1,1,1]来说,这么寻找的话需要进行0->1->4->5->10
这条路径,而不难发现,实际上我们只要通过0->3->5->10
这条路径就能抵达,所以实际答案为4而不是5,问题就出在其实真正能够抵达的最远值不仅与数值有关,还与位置有关
经过第一个想法的思考,想到了第二个解法,去取i后面的n个数,此时 n = n u m s [ i ] n=nums[i] n=nums[i](nums为非负整数数组),取出 n u m s [ j ] + j nums[j] + j nums[j]+j的最大值(j为n中某个数的下标),此时将位置信息与数值信息结合起来,得到最后的答案
class Solution {
public int jump(int[] nums) {
int step = 0;
int index = 0;
while(index < nums.length){
int range = nums[index];
int nextIndex = -1;
int max = -1;
for(int i = Math.min(nums.length - 1,index + range);i >= index + 1;i --){
if(nums[i] + i > max && nextIndex != nums.length - 1){
max = nums[i] + i;
nextIndex = i;
}
}
if(nextIndex == -1)break;
step ++;
index = nextIndex;
}
return step;
}
}