贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的是在某种意义上的局部最优解。
贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择,选择的贪心策略必须具备无后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关。
- 分发饼干—leetcode 445
public static int findContentChildren(int[] g, int[] s) {
Arrays.sort(g);
Arrays.sort(s);
int child = 0;
int cookie = 0;
while(child < g.length && cookie < s.length) {
if(s[cookie] >= g[child]) {
child++;
}
cookie++;
}
return child;
}
- 摆动序列—leetcode376(解法一)
public static int wiggleMaxLength(int[] nums) {
if(nums.length == 2 && nums[0] == 0 && nums[1] == 0) {
return 1;
}
if(nums.length <= 2) {
return nums.length;
}
int up = 1;
int down = 1;
for(int i = 1; i <nums.length; i++) {
if(nums[i] > nums[i-1]) {
up = down + 1;
}
if(nums[i] < nums[i-1]) {
down = up + 1;
}
}
return Math.max(up, down);
}
- 摆动序列—leetcode376(解法二:状态转换)
public static int wiggleMaxLength2(int[] nums) {
if(nums.length == 2 && nums[0] == 0 && nums[1] == 0) {
return 1;
}
if(nums.length <= 2) {
return nums.length;
}
int flag = 0;
int count = 1;
for(int i = 1; i < nums.length; i++) {
switch(flag) {
case 0: {
if(nums[i] > nums[i-1]) {
count++;
flag = 1;
}else if(nums[i] < nums[i-1]){
count++;
flag = 2;
}
break;
}
case 1: {
if(nums[i] < nums[i-1]) {
count++;
flag = 2;
}
break;
}
case 2: {
if(nums[i] > nums[i-1]) {
count++;
flag = 1;
}
break;
}
}
}
return count;
}
- 移掉K位数字—leetcode402
public String removeKdigits(String num, int k) {
//贪心算法+栈
if(k>=num.length()||num.length()==0)
return "0";
//栈顶始终是最大值
Stack<Integer>stack=new Stack<>();
stack.push(num.charAt(0)-'0');
for(int i=1;i<num.length();i++) {
int now=num.charAt(i)-'0';
//可能好几个值都比当前值大,那么我们就在k允许的情况下,去去除它。
while(!stack.isEmpty()&&k>0&&now<stack.peek()){
stack.pop();
k--;
}
//不等于0可以添加进去,
//等于0,栈不为空可以填进去,
if(now!=0||!stack.isEmpty()) {
stack.push(now);
}
}
//56789这种情况,前面一直比后面小,那就去除栈顶,谁让栈顶最大
while(k>0) {
k--;
stack.pop();
}
//10,1(当now=0时,满足条件,去掉1,但now为0,且为空。)
if(stack.isEmpty())
return "0";
StringBuilder sb=new StringBuilder();
while(!stack.isEmpty())
sb.append(stack.pop());
//从后往前添加所以我们要逆序
return sb.reverse().toString();
}
- 跳跃游戏–leetcode55
public boolean canJump(int[] nums) {
int[] index = new int[nums.length];
for(int i = 0; i < nums.length; i++) {
index[i] = nums[i] + i;
}
int jump = 0;
int max_index = index[0];
while(jump < index.length && jump <= max_index) {
if(max_index < index[jump]) {
max_index = index[jump];
}
jump++;
if(jump == index.length) {
return true;
}
}
return false;
}
- 跳跃游戏 II–leetcode45
public int jump(int[] nums) {
if(nums.length <= 2) {
return 0;
}
int current_max_index = nums[0];
int pre_max_index = nums[0];
int count = 1;
for(int i = 1; i < nums.length; i++) {
if(current_max_index < i) {
count++;
current_max_index = pre_max_index;
}
if(pre_max_index < nums[i] + i) {
pre_max_index = nums[i] + i;
}
}
return count;
}
- 用最少数量的箭引爆气球–leetcode452
public int findMinArrowShots(int[][] points) {
if(points.length < 2) {
return points.length;
}
// 按照区间终点进行排序
Arrays.sort(points, new Comparator<int[]>() {
@Override
public int compare(int[] point1, int[] point2) {
if (point1[1] != point2[1]) {
return point1[1] - point2[1];
}else {
return point1[0] - point2[0];
}
}
});
int count = 1;
int end = points[0][1];
for(int i = 1; i < points.length; i++) {
if(points[i][0] > end) {
// 多用一支箭
count++;
end = points[i][1];
}
}
return count;
}