zoukankan      html  css  js  c++  java
  • 贪心总结

    贪心专题

      贪心(Greedy)的问题我接触不多,它的基本思想很像是在递进状态的时候,采取最有利的方向。比如找零问题,有[1,2,5]面额的硬币,找16块钱,贪心的策略就是用最大的面额整除,余数用比当前小的面额继续整除,最后就得到硬币的数量,这里是5*3+1,4枚硬币。

      与动态规划相比,动态规划类似于在f(n-1)到f(n)的过程中,保持f(n-1)是众多子结构中最优的;而贪心则是只选择当前最优的决策,这样导致可能不是全局最优的选择。

      需要使用贪心决策的地方,需要证明在这种决策下能达到全局最优,当然这个证明我是不会,都是靠经验判断。

    55. Jump Game

      这个问题的意思是,从起点开始,每个位置表示你能跳的最大位置 。需要计算的是,从起点开始是否能跳到终点。

      这里可以假设你有一个步长范围,每次你到达一个位置的时候,是否能突破你的最大步长,这样遍历到停止就能知道是否到达终点。

      对于n,它取的是当前步长与最大步长相比,如最大者,非常典型的贪心决策。

    class Solution {
        public boolean canJump(int[] nums) {
            if(nums == null || nums.length == 0){
                return true;
            }
            int reach = nums[0];
            for(int i=0;i<=reach;i++){
                if(reach<i+nums[i])
                    reach = i+nums[i];
                if(reach >= nums.length-1)
                    return true;
            }
            return false;
        }
    
    }

      

    45. Jump Game II

       这个问题是上个问题的基础上,再进了一步。就是要求算出从起点跳用最少的步骤达到终点。

       它的思路,就是在第一问的基础上做一个决策。我们为什么要扩大区间,扩大区间意思是一次能跳的最大步长,那每次都用最大步长去跳就是所求了。变相来说,就是区间扩大的时候,就算是一步。

    class Solution {
        public int jump(int[] nums) {
            if(nums.length <= 1){
                return 0;
            }
    
            int reach = 0;
            int max = 0;
            int times = 0;
            for(int i=0;i<=reach;i++){
                if(i+nums[i] > max){
                    max = i + nums[i];
                }
                if(i == reach){
                    reach = max;
                    times ++;
                    if(reach >= nums.length-1)
                        break;
                }
            }
            return reach >= nums.length-1?times:0;
        }
    }

     12. Integer to Roman

       将十进制数转化为罗马数字。

       使用贪心决策,先转化最大的单位,然后逐个降低单位。

    class Solution {
        public String intToRoman(int num) {
            StringBuilder str = new StringBuilder();
            String symbol[]={"M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"};
            int value[]=    {1000,900,500,400, 100, 90,  50, 40,  10, 9,   5,  4,   1};
            for(int i=0;num!=0;++i)
            {
                while(num>=value[i])
                {
                    num-=value[i];
                    str.append(symbol[i]);
                }
            }
            return str.toString();
        }
    }

    11. Container With Most Water

       小的那端往中间移动,保证大的端。

    class Solution {
        public int maxArea(int[] height) {
            int maxarea = 0, l = 0, r = height.length - 1;
            while (l < r) {
                maxarea = Math.max(maxarea, Math.min(height[l], height[r]) * (r - l));
                if (height[l] < height[r])
                    l++;
                else
                    r--;
            }
            return maxarea;
        }
    }
  • 相关阅读:
    创建git项目的feature分支以及下载特定分支的仓库代码
    C++读取文件
    linux解压eclipse启动时无法找到jre环境的解决办法
    ubuntu安装谷歌浏览器
    web项目脱离Eclipse在Tomcat部署并配置Eclipse调试
    阿里巴巴连接池Druid简单使用
    gc overhead limit exceeded
    onload方法注意点
    获取Spring管理的Bean
    Java应用中使用ShutdownHook友好地清理现场
  • 原文地址:https://www.cnblogs.com/chentingk/p/11691755.html
Copyright © 2011-2022 走看看