• 算法练习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

  • 相关阅读:
    c字符指针与字符数组的区别
    BiLstm原理
    TensorFlow中assign函数
    TensorFlow Training 优化函数
    TensorFlow 神经网络相关函数
    TensorFlow 算术运算符
    TensorFlow函数:tf.reduce_sum
    TensorFlow函数教程:tf.nn.dropout
    TensorFlow占位符操作:tf.placeholder_with_default
    TensorFlow函数:tf.random_shuffle
  • 原文地址:https://www.cnblogs.com/GavinYGM/p/10356199.html
Copyright © 2020-2023  润新知