java常见算法

1.题目描述

观察下面的数字金字塔。

写一个程序来查找从最高点到底部任意处结束的路径,使路径经过数字的和最大。每一步可以走到左下方的点也可以到达右下方的点。

        7 

      3   8 

    8   1   0 

  2   7   4   4 

4   5   2   6   5 

在上面的样例中,从 7 \to 3 \to 8 \to 7 \to 57→3→8→7→5 的路径产生了最大

输入输出样例

输入 #1

5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5

输出 #1

30

import java.util.Scanner;

public class Main4 {

     public static void main(String[] args) {

          Scanner scanner = new Scanner(System.in);
          int n = scanner.nextInt();
          int[][] arr = new int[n][n];
          int[][] count = new int[n][n];

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

               for (int j = 0; j < i + 1; j++) {

                    arr[i][j] = scanner.nextInt();
               }
          }

          count[0][0] = arr[0][0];
          if(n == 1){
               System.out.println(count[0][0]);
               return;
          }

          count[1][0] = arr[1][0]+arr[0][0];
          count[1][1] = arr[1][1]+arr[0][0];


          if(n == 2){
               System.out.println(Math.max(count[0][0]+count[1][0],count[1][1]));
               return;
          }

          int sum = Integer.MIN_VALUE;

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

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

                    if(j == 0)
                         count[i][j] = count[i-1][j]+arr[i][j];

                    else if (j == i)
                         count[i][j] = count[i-1][j-1]+arr[i][j];
                    else {

                         count[i][j] = Math.max(arr[i][j]+count[i-1][j],arr[i][j]+count[i-1][j-1]);
                    }
               }
          }

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

               sum = Math.max(sum,count[n-1][i]);
          }

          System.out.println(sum);
     }
}

发现这个MLE里面的例子有上万行,我的....

优化后的代码

其实可以从下往上走,在走的时候就已经做了判断大小,不需要之前走完还有继续比较

import java.util.Scanner;
 
public class Main {
 
  public static void main(String[] args) {
    // TODO 自动生成的方法存根
    Scanner sc = new Scanner(System.in);
    int n = sc.nextInt();// 数组的行列数
    int[][] num = new int[n][n];
    for (int i = 0; i < n; i++) {// 输入数组
      for (int j = 0; j < i + 1; j++) {
        num[i][j] = sc.nextInt();
      }
    }
    System.out.println(dpd(num));
  }
 
  public static int dpd(int[][] num) {
    int row = num.length;// 定义行数
    int line = num[row - 1].length;// 定义列数
    int[][] dp = new int[row][line];// 定义dp数组
    for (int i = 0; i < line; i++) {// 初始化最后一行
      dp[row - 1][i] = num[row - 1][i];
    }
    for (int i = row - 2; i >= 0; i--) {// 从最后一行向前走 所以i从倒数第二行开始
      for (int j = 0; j <= i; j++) {
        dp[i][j] = num[i][j] + Math.max(dp[i + 1][j], dp[i + 1][j + 1]);
      }
    }
    return dp[0][0];
  }
}

2.题目

某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。

输入导弹依次飞来的高度(雷达给出的高度数据是\le 50000≤50000的正整数),计算这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。

输入 #1

389 207 155 300 299 170 158 65

输出 #1

6

2


import java.util.Scanner;

public class te {
     //动态规划,创建特殊数组
     static int[] len, height, count;
     static int max1, max2;
     public static void dio(int k){
          for (int i = 0; i < k; i++) {
               len[i] = 1;
               count[i] = 1;
               //每一次都与前面的数遍历,只取最大值
               for (int j = 0; j < i; j++) {
                    if(height[i] <= height[j]){
                         len[i] = Math.max(len[i], len[j]+1);
                    }else{
                         count[i] = Math.max(count[i], count[j]+1);
                    }
               }//389 207 155 300 299 170 158 65

               max1 = Math.max(max1, len[i]);
               max2 = Math.max(max2, count[i]);

          }
     }

     public static void main(String[] args) {
          Scanner sc = new Scanner(System.in);
          String arr = sc.nextLine();
          String[] a = arr.split(" ");
          int n = a.length;

          len = new int[n];
          count = new int[n];
          height = new int[n];

          for (int i = 0; i < n; i++) {
               height[i] = Integer.parseInt(a[i]);
          }

          dio(n);
          System.out.println(max1);
          System.out.println(max2);
     }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Java常见算法题有很多,以下是一些常见算法题目及其解决方法。 1. 求两个整数的最大公约数和最小公倍数。可以使用辗转相除法来求最大公约数,即不断用较大数除以较小数,直到余数为0,则较小数就是最大公约数。最小公倍数等于两数的乘积除以最大公约数。 2. 数组中找出第K大(小)的数。可以使用快速排序的思想,选取一个基准元素,将数组分为大于基准元素和小于基准元素的两部分,递归地在其中一部分中查找第K大(小)的数。 3. 判断一个字符串是否为回文串。可以使用双指针法,分别从字符串的开头和结尾开始遍历,判断对应字符是否相等,直到两指针相遇或交叉。 4. 实现链表的反转。可以使用迭代或递归的方式,将当前节点的下一个节点指向上一个节点,然后继续遍历链表。 5. 实现二分查找算法。对于有序数组,可以使用二分查找法,在数组的中间位置判断目标值与中间值的大小关系,然后缩小查找范围,直到找到目标值或查找范围为空。 6. 实现图的深度优先搜索(DFS)和广度优先搜索(BFS)。DFS使用递归的方式进行搜索,遍历当前节点的邻接节点,直到遍历完所有节点或找到目标节点。BFS使用队列进行搜索,将当前节点的邻接节点加入队列,并依次出队访问,直到找到目标节点或队列为空。 以上只是一些常见算法题目,掌握这些算法可以帮助我们更好地理解和解决实际问题。当然,还有许多其他的算法题目,不断学习和练习才能更好地掌握。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

海边的彩虹与你

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值