概念:
1.整体与局部,贪心算法以局部最优解为目的,做出局部上的最佳选择,希望以此来得到,整体的最优解。
2.贪心算法的难点在于 【 证明 】 ,你怎么知道局部最优,就是整体最优的?有时候,可能只是想当然。
3.贪心和动态规划,目的都是取得最优解,不一定哪个难,因为,贪心压根就没固定解法,,,挺玄学。
例题1 最值贪心:
给定字符串NUM,求,NUM中,所有非空子字符串的,最大奇数
以字符串类型返回,没找到回空
char * largestOddNumber(char * num){
int i; // (1)
int len = strlen(num); // (2)
for(i = len-1; i >= 0; --i) { // (3)
if((num[i] - '0') & 1) { // (4)
num[i+1] = '\0'; // (5)
return num; // (6)
}
}
num[i+1] = '\0'; // (7)
return num;
}
代码1.1最值贪心
从后往前遍历,找最先发现的奇数
***
例题2 分割贪心
给定一个字符串,这个字符串中,含有相同数量的,‘L','R' ,称这个字符串为【平衡字符串】
尽可能多的分割这个字符串,求,最多能得到多少平衡字符串
int balancedStringSplit(char * s){
int i;
int sum = 0; // (1)
int ans = 0; // (2)
for(i = 0; s[i]; ++i) {
sum += (s[i] == 'L') ? 1 : -1; // (3)
if(sum == 0) {
++ans; // (4)
}
}
return ans; // (5)
}
代码1.2分割贪心
定义一个计数器,出现一对L,R,就+1
例题3:排序贪心
给定一个长度小于1000的,非负整数数组,求这个数组中,最多能,组成多少个三角形。
int cmp(const void *a, const void *b) {
return *(int *)a - *(int *)b;
}
int triangleNumber(int* nums, int numsSize){
int i, j, k;
int ans = 0;
qsort(nums, numsSize, sizeof(int), cmp); // (1)
for(i = 0; i < numsSize; ++i) {
j = i + 1;
k = j + 1; // (2)
while(j < numsSize) {
while(k < numsSize) {
if(nums[i] + nums[j] <= nums[k]) {
break; // (3)
}
++k;
}
ans += k-j-1; // (4)
++j; // (5)
if(k == j) k++;
}
}
return ans;
}
代码1.3排序贪心
练习题1 玩筹码 1217
class Solution: def minCostToMoveChips(self, position: List[int]) -> int: