• 面试基础算法题


    动态规划求数组中最长的上升序列(LongestIncreasingSubsequence)的个数,复杂度为O(n^2)。

    例如:数组int  arr[] = {7,3,5,9,4,6,8,10},最长上升序列应该为3,5,6,8,10或3,4,6,8,10 ,最终答案应该为5;

    dp[i]表示数组中以下标i结尾的最长上升序列的个数,则原问题就转换为了求所有dp[i](0<=i<len)中的最大值;

    而每一个dp[i]又是以下标i结尾的所有序列中最长上升序列的个数。

    import java.util.Scanner;
    public class Main
    {
        
        public static void main(String[] args) throws Exception
        {
            Scanner sc = new Scanner(System.in);
            while(sc.hasNext())
            {
                int n = sc.nextInt();
                int[] arr = new int[n];
                for(int i= 0;i<n;i++)
                {
                    arr[i] = sc.nextInt();
                }
                 System.out.println(maxLIS(arr));
            }
        }
     
          public static int  maxLIS(int[] arr)
          {
             int max = 1;
             int len = arr.length;
             int[] dp = new int[len];
             dp[0] = 1;
             for(int i=1;i<len;i++)
             {
               for(int j =0;j<i;j++)
               {
                if(arr[i]>arr[j])
                  dp[i] = Math.max(dp[i],dp[j]+1);
               }
             max = Math.max(dp[i],max);
             }
            return max;
          }    
    }

    2.动态规划求连续子数组最大和。

    package ers;
    
    import java.util.Scanner;
    public class Main
    {
        
        public static void main(String[] args) throws Exception
        {
            Scanner sc = new Scanner(System.in);
            while(sc.hasNext())
            {
                int n = sc.nextInt();
                int[] arr = new int[n]; 
                for(int i= 0;i<n;i++)
                {
                    arr[i] = sc.nextInt();
                }
                 System.out.println(maxLIS(arr));
            } 
        } 
      
          public static int  maxLIS(int[] arr)
          {
             int len = arr.length;
             int[] dp = new int[len]; //动态规划记录
             dp[0] = arr[0];//初始为第一个数
             int start = 0, end = 0;  //记录最大子数组的起始位置(在数组中的下标)
             int MaxSumSub;  //最大子数组的值
             MaxSumSub = dp[0];  //最大值初始为第一个数
             int temp = 0;  //
             for(int i = 1; i < len; i++)
             {
                 if(dp[i - 1] <= 0)  //前面的<0,直接丢弃
                 {
                     dp[i] = arr[i];
                     temp = i; //记录起始为止
                 }
                 else
                     dp[i] = arr[i] + dp[i - 1];  //往后求和
                 if(dp[i] > MaxSumSub)  //找到到i为止的最大子数组
                 {
                     MaxSumSub = dp[i];  //最大...
                     start = temp;  //标记起始
                     end = i;  //标记此时的结束位置
                 }
             }
             for(int j =start;j<=end;j++)
                 System.out.print(arr[j]+" ");
             System.out.println();
            return MaxSumSub;
          }    
    }
  • 相关阅读:
    面对满足正态分布的事情,我们如何增加成功概率
    《灭火:美国金融危机及其教训》笔记
    《失控:机器、社会与经济的新生物学》笔记
    外推谬误
    迎接未来,我们可以做什么
    怎样理解帝国与王朝的兴衰,以及它对组织管理有何启示?
    vue中$emit的用法,父子组件传值及页面跳转之间传值
    SharePoint Online 调用PnP.js 搜索返回结果不完整
    SharePoint REST API 的 Expand 方法
    SharePoint Online PnPjs 批量更新项目
  • 原文地址:https://www.cnblogs.com/mrdblog/p/7513984.html
Copyright © 2020-2023  润新知