zoukankan      html  css  js  c++  java
  • 贪心算法

    Leetcode 455 分发饼干

    需求因子:饼干

    1.对饼干和孩子排序,方便比较

    2.当一个孩子能被多个饼干满足时,要挑选哪个饼干

    3.一个饼干能满足多个孩子时,要选哪个孩子 

    思路:对两个数组排序,用最小号的饼干分配给最小胃口的孩子

    class Solution {
        public int findContentChildren(int[] g, int[] s) {
            Arrays.sort(g);
            Arrays.sort(s);
            int index = 0;
            int sum = 0;
            for(int i=0;i<s.length;i++)
            {
                if(index<g.length)
                {
                    if(s[i]>=g[index]) 
                    {
                        index++;
                        sum++;
                    }
                } 
            }
    
            return sum;
        }
    }

    Leetcode 376 摇摆序列

    https://leetcode-cn.com/problems/wiggle-subsequence

    如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为摆动序列。第一个差(如果存在的话)可能是正数或负数。少于两个元素的序列也是摆动序列。

    例如, [1,7,4,9,2,5] 是一个摆动序列,因为差值 (6,-3,5,-7,3) 是正负交替出现的。相反, [1,4,7,2,5] 和 [1,7,4,5,5] 不是摆动序列,第一个序列是因为它的前两个差值都是正数,第二个序列是因为它的最后一个差值为零。

    给定一个整数序列,返回作为摆动序列的最长子序列的长度。 通过从原始序列中删除一些(也可以不删除)元素来获得子序列,剩下的元素保持其原始顺序。

    思路:分析过程,递增过程中选择最大的元素,递减过程中选择最小的元素

    扫描过程中三个状态的转换:

     

    使用switch case

    (java类常量: public static final int )

    (switch case中能够使用到变量:int short char String)

    class Solution {
        public static final int begin = 0;
        public static final int up = 1;
        public static final int down = 2;
    
        public int wiggleMaxLength(int[] nums) {
            if(nums.length==0) return 0;
    
            int sum = 0;
    
            int state = begin;
            for(int i=0;i<nums.length-1;i++)
            {
                switch(state)
                {
                    case begin:
                        if(nums[i]<nums[i+1]) 
                        {
                            //System.out.print("A"+nums[i]+" ");
                            sum++;
                            state = up;
                        }
                        else if(nums[i]>nums[i+1]) 
                        {
                            //System.out.print("B"+nums[i]+" ");
                            sum++;
                            state = down;
                        }
                        break;
                    
                    case up:
                        if(nums[i]>nums[i+1])
                        {
                            //System.out.print("C"+nums[i]+" ");
                            state = down;
                            sum++;
                        }
                        break;
                    case down:
                        if(nums[i]<nums[i+1])
                        {
                            //System.out.print("D"+nums[i]+" ");
                            state = up;
                            sum++;
                        }
                        break;
                }  
            }
            sum++;
            return sum;
        }
    }

    Leetcode 402 移除k个数字

    https://leetcode-cn.com/problems/remove-k-digits

    给定一个以字符串表示的非负整数 num,移除这个数中的 k 位数字,使得剩下的数字最小。

    示例 1 :

    输入: num = "1432219", k = 3

    输出: "1219"

    解释: 移除掉三个数字 4, 3, 2 形成一个新的最小的数字 1219

    思路1 使用StringBuilder,删k轮,每次删一个高位大数或最后一个数。

    String → StringBuilder : StringBuilder s = new StringBuilder(str);

    StringBuilder → String : String str = s.toString();

    StringBuilder的方法:

    class Solution {
        public String removeKdigits(String num, int k) {
            if( k>= num.length()||num.length()==0) return "0";
            StringBuilder s = new StringBuilder(num);
            boolean flag = false;
            for(int i=0;i<k;i++)
            {
                flag = false;
                for(int j=0;j<s.length()-1;j++)
                {
                    if(s.charAt(j)>s.charAt(j+1))
                    {
                        s.delete(j,j+1);
                        flag = true;
                        break;
                    }
                }
                if(!flag) s.delete(s.length()-1,s.length());
            }
    
            while(s.charAt(0)=='0' && s.length()>1)
            {
                s.delete(0,1);
            }
            return s.toString();
        }
    }

    思路2: 栈+贪心算法

    思路有点难想到。星星 星星 星星

    1.char 封装类是 Charater

    2.使用stringbuilder.append(字符串/字符)追加

    3.String对象有charAt(index)方法返回字符

    class Solution {
        public String removeKdigits(String num, int k) {
            if(num.length()==0 || k >= num.length()) return "0";
    
            Stack<Character> stack = new Stack<>();
            stack.push(num.charAt(0));for(int i=1;i<num.length();i++)
            {
                char now = num.charAt(i);
                while(!stack.isEmpty()&&k>0&&now<stack.peek())
                {
                    stack.pop(); 
                    k--;
                }
                
                stack.push(now);
                
            }
            while(k>0)
            {
                stack.pop();
                k--;
            }
            Stack<Character> s = new Stack<>();
            while(!stack.isEmpty())
            {
                s.push(stack.pop());
            }
            StringBuilder sb = new StringBuilder();
            boolean fz = true;
            while(!s.isEmpty())
            {
                if(sb.length()==0&&s.peek()=='0') s.pop();
                else sb.append(s.pop());
            }
    
            if(sb.length()==0) return "0";
            return sb.toString();
            
    
        }
    }
    
    

    Leetcode 55 跳跃游戏 

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

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

    判断你是否能够到达最后一个位置。

    思路:关键是判断最优的跳跃路径,跳到的下一个位置能跳到的最远位置要最远

    class Solution {
        public boolean canJump(int[] nums) {
    
            if(nums.length<=1) return true;
            int max = 0; 
            for(int i=0;i<nums.length;)
            {
                int temp = i;
                int maxnow = max;
                for(int k=0;k<=nums[i];k++)
                {
                    if(i+k+nums[i+k]>max) 
                    {
                        max = k+i+nums[i+k];
                        if(max>=nums.length-1) return true;
                        temp = i+k;
                    }
                }
                i=temp;
                if(maxnow==max&&max<nums.length-1) return false;
            }
            return false;
    
        }
    }

    Leetcode 452 射气球 

    在二维空间中有许多球形的气球。对于每个气球,提供的输入是水平方向上,气球直径的开始和结束坐标。由于它是水平的,所以y坐标并不重要,因此只要知道开始和结束的x坐标就足够了。开始坐标总是小于结束坐标。

    一支弓箭可以沿着x轴从不同点完全垂直地射出。在坐标x处射出一支箭,若有一个气球的直径的开始和结束坐标为 xstartxend, 且满足  xstart ≤ x ≤ xend,则该气球会被引爆。

    思路1:

    1.将气球的右端点进行排序!!从尾部开射

    2.判断一个弓箭手最多能射几个气球,尽可能多射

    3. Arrays的自定义排序算法

    class Solution {
        public int findMinArrowShots(int[][] points) {
            if(points.length<1) return 0;
            Arrays.sort(points, new Comparator<int[]>() {
                public int compare(int[] a,int[] b) {
                    return a[1]-b[1];
                }
            });
            
            int sum = 0;
            for(int i=0;i<points.length;)
            {
                sum++;
                int k=i+1;
                if(k>points.length-1) break;
                while(points[i][1]>= points[k][0])
                {
                    k++;
                    if(k>points.length-1) break;
                }
                i=k;
            }
            return sum;
        }
    }

    思路2:

    1.将气球的左端点进行排序!!从头部开射

    2.判断一个弓箭手最多能射几个气球,尽可能多射

    class Solution {
        public int findMinArrowShots(int[][] points) {
            if(points.length<1) return 0;
            Arrays.sort(points, new Comparator<int[]>() {
                public int compare(int[] a,int[] b) {
                    return a[0]-b[0];
                }
            });
            
            int sum = 0;
            int end = 0;
            for(int i=0;i<points.length;)
            {
                sum++;
                int k=i+1;
                end = points[i][1];
                if(k>points.length-1) break;
                while(points[k][0]<=end)
                {
                    if(points[k][1]<end) end = points[k][1];
                    k++;
                    if(k>points.length-1) break;
                }
                i=k;
            }
            return sum;
        }
    }

    Leetcode 871 最低加油次数

  • 相关阅读:
    kettle参数、变量详细讲解[转]
    C# 异步
    〖Python〗-- 模块与包
    〖Python〗-- 异常处理
    〖Python〗-- 面向对象进阶
    〖Python〗-- 反射、内置attr、包装
    〖Python〗-- property、静态方法、类方法
    〖Python〗-- 面向对象编程的继承、多态与多态性、封装
    〖Python〗-- 面向对象编程、继承、组合、接口和抽象类
    〖Python〗-- 递归、面向对象初识及编程思想
  • 原文地址:https://www.cnblogs.com/luiyuying/p/12704607.html
Copyright © 2011-2022 走看看