算法--贪心算法

目录

贪心算法思想

贪心算法案例

分发饼干

跳跃游戏 

背包问题

最大整数

性能分析

优越性

局限性


贪心算法思想

        贪心算法是指求解问题时,会做出在当前看来最优的选择。也即是不考虑整体的最优解,仅考虑局部最优解。

        贪心算法关键在于贪心策略的选择。贪心选择的意思是对于所求问题的整体最优解,可以通过一系列的局部最优选择求得。需要注意的是,贪心选择须具备无后效性,也即是某个状态不会影响之前求得的局部最优解。

        求解步骤

        1.将问题分解为若干个子问题

        2.找出合适的贪心策略

        3.求解每一个子问题的最优解

        4.将局部最优解堆叠成全局最优解

贪心算法案例

分发饼干

假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。

对每个孩子 i,都有一个胃口值 g[i],这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j,都有一个尺寸 s[j] 。如果 s[j] >= g[i],我们可以将这个饼干 j 分配给孩子 i ,这个孩子会得到满足。你的目标是尽可能满足越多数量的孩子,并输出这个最大数值。

来源:力扣(LeetCode)
链接:力扣

        分析:利用贪心思想来看待这道题,就是要尽可能满足更多的孩子。 那么在饼干数量有限的情况下,我们就得先满足胃口小的孩子,再去满足胃口大的孩子,这样才能保证能够满足更多的孩子。

/**
 * @param {number[]} g
 * @param {number[]} s
 * @return {number}
 */
var findContentChildren = function(g, s) {
    g.sort((a,b) => (a-b));  //从小到大排序
    s.sort((a,b) => (a-b));
    let children = 0;   //孩子指针
    let yummy = 0;      //饼干指针
    while(children < g.length && yummy < s.length){
        if(g[children] <= s[yummy]){
            children++;
        }
        yummy++;
    }
    return children;
};

跳跃游戏 

给定一个非负整数数组 nums ,你最初位于数组的第一个下标 。

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

判断你是否能够到达最后一个下标。

来源:力扣(LeetCode)
链接:力扣

        分析:首先我们分析题目,要到达最后一个位置, 就需要最后一跳的距离加上该位置下标能够大于等于数组长度,然后依次往前推,当前元素也处于前一个元素最远可以到达的范围之内,这也即是贪心算法的思想。

/**
 * @param {number[]} nums
 * @return {boolean}
 */
var canJump = function(nums) {
    let max = 0;
    for(let i=0;i<nums.length;i++){
        if(i > max){
            return false;
        }
        max = Math.max(max, i + nums[i]);  //取较大值
        if(max >= nums.length - 1){
            return true;
        }
    }
    return false;
};

背包问题

 有一个背包,背包容量是M=200。有8个物品,物品可以分割成任意大小。

要求尽可能让装入背包中的物品总价值最大,但不能超过总容量。

物品ABCDEFGH
重量1025605035153055
价值510201530203010

        分析:首先我们要先获得每一种物品单位重量的价值,依据贪心选择策略,在不超过背包容量的情况下,将尽可能多的单位重量价值最高的物品装入背包,直至背包装满。

function backpage(All,weight,value){
    let arr = [];
    for(let i=0;i<weight.length;i++){
        let obj = {
            name:String.fromCharCode(65+i), //物品名称
            wei:weight[i],   //物品重量
            val:value[i],    //物品价值
            val_wei:(value[i]/weight[i]).toFixed(2), //获取价值比
            get:false   //标记物品是否存入背包
        }
        arr.push(obj);
    }
    let weightAll = 0;  //总重量
    let valueAll = 0;   //总价值
    let max = 0;        //当前最高价值
    let array = [];     //放入背包物品顺序表
    let flag = 0;       //获取价值比最高物品索引
    let n = 0;          //最终放入背包物品索引

    //将arr数组按照价值比进行从大到小排序 
    for(let m=0;m<weight.length;m++){
        for(let n=m+1;n<weight.length;n++){
            if(arr[m].val_wei < arr[n].val_wei){
                let temp = arr[m];
                arr[m] = arr[n];
                arr[n] = temp;
            }
        }
    }

    while(weightAll <= All){
        max = arr[weight.length-1].val_wei;  //获取最小价值比作为初始max
        for(let j=0;j<weight.length;j++){
            if(arr[j].val_wei > max && arr[j].get === false){
                max = arr[j].val_wei;
                flag = j;
            }
        }
        array[n++] = arr[flag].name;
        arr[flag].get = true;   //标记物品已放入背包
        weightAll += arr[flag].wei;  //计算总容量
        valueAll += arr[flag].val;    //计算总价值
    }
    let str = "";
    for(let k=0;k<n-1;k++){
        str += array[k] + '\t';
    }
    console.log("最终放入背包中的物品有",str);
    console.log("物品总重量为",weightAll-arr[flag].wei);
    console.log("物品总价值为",valueAll-arr[flag].val);
}
backpage(200,[10,25,60,50,35,15,30,55],[5,10,20,15,30,20,30,10]);

所得结果:

 

最大整数

设有n个正整数,将它们连接成一排,组成一个最大的多位整数。 
例如:n=3时,3个整数13,312,343,连成的最大整数为34331213。 
又如:n=4时,4个整数4,7,13,246,连成的最大整数为7424613。

        分析: 首先先将整数转换为字符串,然后比较a+b和b+a,将大的放在前面,小的放在后面,如此反复便可得出最大整数

function maxNum(nums){
    let last = "";
    for(let i=0;i<nums.length;i++){
        for(let j=i+1;j<nums.length;j++){
            let num1 = nums[i] + "";  //数字转字符串
            let num2 = nums[j] + "";
            if((num1+num2) < (num2+num1)){
                let temp = nums[j];
                nums[j] = nums[i];
                nums[i] = temp;
            }
        }
    }
    for(let i=0;i<nums.length;i++){
        last += nums[i];
    }
    return last;
}
let max = maxNum([12,121,23,42,1,6,71,21]);
console.log("组成最大整数:"+max);   //组成最大整数:716422321121211

性能分析

优越性

        1.适合用于组合优化问题

        2.能做出在当前来看最好的选择

局限性

        1.不能保证求得的解整体来看是最优解,并非所有问题都可以通过局部最优解得到整体最优解

        2.无法用来求解最大或者最小问题

        3.只能用来求解满足某些约束条件的可行解的范围

        4.贪心的选择需要具备无后效性条件

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值