算法练习LeetCode初级算法之动态规划

  • 爬楼梯:斐波那契数列

    假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

    每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

    注意:给定 n 是一个正整数。

  • 非递归解法

    class Solution {

    public int climbStairs(int n) {

        if (n==1) {

                return 1;

            }

        if (n==2) {

                return 2;

            }

        int n1=1,n2=2;

        for (int i = 0; i <n-2; i++) {

                int m=n1+n2;

                n1=n2;

                n2=m;

            }

    return n2;

    }

    }

  • 递归解法

    class Solution {

        int[] result=null;

    public int climbStairs(int n) {

        result=new int[n+1];

    Arrays.fill(result, -1);

    f(n);

    return result[n];

    }

    private void f(int X) {

        if (result[X]!=-1) {

                return;

            }

        if (X==0||X==1) {

                result[X]=1;

                return;

            }

            f(X-1);

            f(X-2);

        result[X]=result[X-1]+result[X-2];

        }

    }

  • 买卖股票的最佳时机

    重点是要设置一个最小值和一个最大值,并且不断替换!

    class Solution {

    public int maxProfit(int[] prices) {

    if (prices.length==0||prices.length==1) {

                return 0;

            }

    int minPrice=prices[0];

    int maxPrice=0;

    for (int i = 0; i < prices.length; i++) {

                if (prices[i]<=minPrice) {

                    minPrice=prices[i];

                }else if ((prices[i]-minPrice)>maxPrice) {

                    maxPrice=prices[i]-minPrice;

                }

            }

    return maxPrice;

    }

    }

  • 最大子序和

  • 超出时间限制的解法

    class Solution {

    public int maxSubArray(int[] nums) {

    if (nums.length==0) {

                return 0;

            }

        if (nums.length==1) {

                return nums[0];

            }

    int sum=0;

    Set<Integer> list=new TreeSet<>();

    int n=1;

    while (n<=nums.length) {

        for (int i = 0; i < nums.length-n+1; i++) {

            int m=0;

                    for (int j = 0; j < n; j++) {

                        m+=nums[i+j];

                    }

                    list.add(m);

                }

        n++;

            }

    int res=0;

    for (Iterator iterator = list.iterator(); iterator.hasNext();) {

                res= (Integer) iterator.next();

            }

    return res;

    }

    }

  • 优化解法

没想到可以这样解,厉害!找个例子试一试就懂了

class Solution {

    public int maxSubArray(int[] nums)

    {

        if (nums.length==0) {

            return 0;

        }

        if (nums.length==1) {

            return nums[0];

        }

        int max=nums[0];

        int sum=0;

        for (int i = 0; i < nums.length; i++) {

            if (sum>0) {

                sum+=nums[i];

            }else {

                sum=nums[i];

            }

            max=Math.max(max, sum);

        }

        return max;

    }    

}

  • 更简单的解法:找最大子序列,最重要的要分清正负!!!

    class Solution {

        public int maxSubArray(int[] nums)

        {

            int max=nums[0];

            int sum=nums[0];

            for (int i = 1; i < nums.length; i++) {

                sum=Math.max(sum+nums[i], nums[i]);

                max=Math.max(max, sum);

            }

            return max;

        }    

    }

  • 打家劫舍

挺难的,参考别人的解法,先记住

  • 递归法

    class Solution {

        //测试2,1,1,2

        private int[] memo;

    public int rob(int[] nums) {

        memo=new int[nums.length];

        Arrays.fill(memo, -1);

        return tryRob(nums, 0);

    }

    private int tryRob(int[] nums,int index) {

            if (index>=nums.length) {

                return 0;

            }

            if (memo[index]!=-1) {

                return memo[index];

            }

        int res=0;

        for (int i = index; i < nums.length; i++) {//循环每次后移,即可以跳过(相隔)两个或多个

                res=Math.max(res, nums[i]+tryRob(nums,i+2));

            }

        memo[index]=res;

        return res;

        }

    }

  • 动态规划

    class Solution {

        //测试2,1,1,2

    public int rob(int[] nums) {

    int n = nums.length;

    if (n == 0) {

    return 0;

    }

    if (n==1) {

                return nums[0];

            }

    if (n==2) {

                return Math.max(nums[0], nums[1]);

            }

    int[] f = new int[n];

    f[0]=nums[0];

    f[1]=Math.max(nums[0], nums[1]);//典型动态规划问题,先将子问题记录,然后

    for (int i = 2; i < f.length; i++) {

                f[i]=Math.max(f[i-2]+nums[i], f[i-1]);//这里利用子问题来解决问题

            }

    return f[n-1];

    }

    }

    参考:https://blog.csdn.net/likunkun__/article/details/80724683

posted @ 2019-02-08 15:03  GavinYGM  阅读(239)  评论(0编辑  收藏  举报