zoukankan      html  css  js  c++  java
  • 算法练习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

  • 相关阅读:
    ubuntu golang nginx
    如何写易于调试的代码
    Topic 2: golang string operation
    topic 1: golang file operation
    【转帖】ArtisticStyle----很好用的C/C++样式格式化工具
    【转帖】C++经典书籍汇总
    (转载)MonoBehaviour的事件和具体功能总结
    unity3d的延时调用函数
    unity3D 实现手机的双指触控和Input类touch详解
    Lua 关于"."与":"号的用法区别
  • 原文地址:https://www.cnblogs.com/GavinYGM/p/10356199.html
Copyright © 2011-2022 走看看