【leetCode】贪婪算法

目录

L55. canJump

L45.Jump2

L402. Remove K Digits


每个阶段都选择局部最优,算法终止时,希望局部最优=全局最优,如果不相等,则得到的是一个次最优解。

L55. canJump

 /**
     * 给出一组非负数,每个数的意思是能跳几步,然后看能不能跳到最后
     * @param nums
     * @return
     */
    public boolean canJump(int[] nums) {

        //贪心算法,从第一个位置,记录能达到的最远距离
        int len = nums.length-1;
        int curMax = nums[0];

        for(int i=0; i<=curMax; i++){ //这里curMax,是能走到的最远距离
            if(nums[i]+i >= len) return true;
            curMax = Math.max(curMax,nums[i]+i);
        }
        return false;
    }

L45.Jump2

 /** 顺藤摸瓜
     * 求跳到最后的最少的跳跃次数
     * @param nums
     * @return
     */
    public int jump(int[] nums) {
        int end = 0; //能跳到的最后的边界
        int maxPos = 0;
        int steps = 0;

        for(int i=0;i<nums.length-1;i++){
            //找能跳的最远的
            maxPos = Math.max(nums[i]+i,maxPos);
            if(end == i){  //如果已经跳到本次边界,则进行更新,否则继续遍历,找跳的最远的max
                end = maxPos;
                steps++;
            }
        }
        return steps;
    }

    /**
     * 顺瓜摸藤
     * @param nums
     * @return
     */
    public int jump2(int[] nums){
        int pos = nums.length -1;//当前指向的位置
        int steps = 0;

        while (pos !=0){
            for(int i=0; i< pos;i++){
                if(nums[i]+i >= pos){
                    pos = i;
                    steps++;
                    break;
                }

            }
        }

        return steps;
    }

L402. Remove K Digits

给出一个字符串,移除指定k个数,使剩下的数最小.

思路:

  • 首先就是遍历字符串num,然后进行while循环的判断,当当前字符比res字符串的最后一个小时,删除res的最后一个字符,之后拼上。while k次判断。
  • 特殊情况1:万一遍历完了k还是!=0,比如99999移除3个,这种情况,就需要把res取前0~n-k个zifu
  • 特殊情况2:遍历完了,前边一堆0,比如1000421移除2元素,00021这种,就需要把前边的一堆0去掉
  • 特殊情况3:如果最后字符串是空,比如99移除2元素,就是"",这种直接返回”0“,在return里判断
public String removeKdigits(String num, int k) {

        String sb = "";
        //就是遍历字符串,当cur char小于前边最后一位的char时,进行更新
        for(int i=0;i<num.length();i++){

            while (k>0 && i>0 && (sb.length()>0) && (sb.charAt(sb.length()-1) > num.charAt(i))){
                sb = sb.substring(0,sb.length()-1);
                k--;
            }
            //需要写到外边哈,不管是大于还是小于,都需要拼接
            sb = sb + num.charAt(i);
        }

        sb = (sb.length() == k)? "":sb.substring(0,sb.length()-k);//取前n-k个数,比如999这种
        //去掉前边的'0'
        while(!sb.isEmpty() && sb.charAt(0) == '0'){
            sb = sb.substring(1,sb.length());
        }

        return sb.isEmpty()? "0":sb ;
    }

L406. Queue Reconstruction by Height

题目:就是给出一组二维数组,第一个元素是高度,第二个元素是他前边有几个人

思路:

  • 首先就是给这个二维数组,按身高降序排列,如果俩人身高一样,就按前边人数的index升序排
  • 之后就是整一个list,遍历新的数组嘛,不断地把元素插进去(按照前边有几个人的这种index),list如果index1有元素,那么再add(1,obj)时就顺移。
    public int[][] reconstructQueue(int[][] people) {

        //首先按照身高和k排序,身高相同返回Index差,身高不同,返回身高差
        //注意index递增,身高递减
        Arrays.sort(people, new Comparator<int[]>() {
            @Override
            public int compare(int[] o1, int[] o2) {
                return o1[0]==o2[0]?o1[1]-o2[1]:o2[0]-o1[0];
            }
        });

        List<int[]> list = new ArrayList<>();
        for (int[] p : people){
            System.out.println(p[1]);
            list.add(p[1], p);//如果对应位置有数,就会后移
        }
        int n=people.length;
        return list.toArray(new int[n][2]);
    }

猜你喜欢

转载自blog.csdn.net/muyimo/article/details/106163209