当前位置: 首页 > news >正文

华为OD-E卷 - 最大矩阵和 100分(java)

题目
给定一个二维整数矩阵,要在这个矩阵中选出一个子矩阵,使得这个子矩阵内所有的数字和尽量大,我们把这个子矩阵称为和最大子矩阵,子矩阵的选取原则是原矩阵中一块相互连续的矩形区域

输入描述
输入的第一行包含2个整数n, m(1 <= n, m <= 10),表示一个n行m列的矩阵,下面有n行,每行有m个整数,同一行中,每2个数字之间有1个空格,最后一个数字后面没有空格,所有的数字的在[-1000, 1000]之间
输出描述
输出一行一个数字,表示选出的和最大子矩阵内所有的数字和
用例
用例一:
输入:

3 4
-3 5 -1 5
2 4 -2 4
-1 3 -1 3

输出:

20
注:5 -1 5 最大值矩阵
    4 -2 4
    3 -1 3

java代码

方法一

将每一个小矩形的长宽情况都列举出来,再根据每次所列出的长宽,将给出的大矩形切割,获得最大和。(此方法时空复杂度较高)

package odTest;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Scanner;

public class maxMatrix {
	static List<Integer> maxList= new ArrayList<>();
	static int line;
	static int column;
	static int wide;
	static int hight;
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		int[] inputRefers =Arrays.stream(scanner.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray();
		line = inputRefers[0];
		column = inputRefers[1];
		
		int[][] matrix =new int[inputRefers[0]][inputRefers[1]];
		for(int i=0;i<inputRefers[0];i++) {
			int[] inputLine = Arrays.stream(scanner.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray();
			for(int j=0;j<inputLine.length;j++) {
				matrix[i][j]=inputLine[j];
			}
		}
		judgeMean(matrix);
		Collections.sort(maxList, new Comparator<Integer>() {
			@Override
			public int compare(Integer arg0, Integer arg1) {
				return arg1-arg0;
			}
		});
		System.out.println(maxList.get(0));
	}

	private static void judgeMean(int[][] matrix) {
		//控矩形边的宽高长度
		for(int i=0;i<line;i++) {
			for(int j=0;j<column;j++) {
				wide = j+1;
				hight = i+1;
//				System.out.println("宽:"+wide+"高:"+hight);
				buildOriginPoint(matrix);
			}
		}
	}
	private static void buildOriginPoint(int[][] matrix) {
		for(int i=0;i<line;i++) {
			for(int j=0;j<column;j++) {
				//传入初始起点
				findMaxVal(matrix,i,j);
			}
		}
	}

	private static void findMaxVal(int[][] matrix, int originX, int originY) {
		//当初始起点超过给出矩阵的长度,直接返回。
		if(originX+hight>line) {
			return;
		}
		if(originY+wide>column) {
			return;
		}
		int sum = 0,max = 0;
		//这里再根据确定的长宽,分别找到对应的和。
		for(int i=0;i<hight;i++) {
			for(int j=0;j<wide;j++) {
				sum = sum+matrix[originX+i][originY+j];
			}
		}
		max = max<sum?sum:max;
//		System.out.println(sum);
		maxList.add(max);
	}
}

方法二

此方法,通过每一次循环得到每一列的和,通过相加列来判断最大和。采用 了Kadane’s Algorithm(卡丹算法)。

package odTest;

import java.util.Scanner;

public class maxMatrix1 {
	 public static void main(String[] args) {
	        Scanner input = new Scanner(System.in);

	        // 读取矩阵的行数(rows) 和 列数(cols)
	        int rows = input.nextInt();
	        int cols = input.nextInt();

	        // 读取矩阵数据
	        int[][] grid = new int[rows][cols];
	        for (int i = 0; i < rows; i++) {
	            for (int j = 0; j < cols; j++) {
	                grid[i][j] = input.nextInt();
	            }
	        }

	        // 计算并输出最大子矩阵和
	        System.out.println(findMaxSum(grid, rows, cols));
	    }

	    // 计算二维矩阵中的最大子矩阵和
	    public static int findMaxSum(int[][] grid, int rows, int cols) {
	        int maxSum = Integer.MIN_VALUE;

	        // 枚举上边界 top
	        for (int top = 0; top < rows; top++) {
	            int[] colSum = new int[cols]; // 列压缩数组,存储 top 到 bottom 之间的列和

	            // 枚举下边界 bottom
	            for (int bottom = top; bottom < rows; bottom++) {
	                // 计算 top 到 bottom 之间的列和
	                for (int col = 0; col < cols; col++) {
	                    colSum[col] += grid[bottom][col];
	                }

	                // 在压缩后的数组上求最大子数组和(Kadane's Algorithm)
	                maxSum = Math.max(maxSum, kadane(colSum));
	            }
	        }

	        return maxSum; // 返回最大子矩阵和
	    }

	    // 使用 Kadane's Algorithm 计算一维数组的最大子数组和
	    private static int kadane(int[] arr) {
	        int maxCurrent = arr[0], maxGlobal = arr[0];

	        // 遍历数组,计算最大连续子数组和
	        for (int i = 1; i < arr.length; i++) {
	            maxCurrent = Math.max(arr[i], maxCurrent + arr[i]); // 选择是否包含之前的子数组
	            maxGlobal = Math.max(maxGlobal, maxCurrent); // 更新最大和
	        }

	        return maxGlobal;
	    }

}

相关文章:

  • 三参数水质在线分析仪:从源头保障饮用水安全
  • 《2025年软件测试工程师面试》消息队列面试题
  • CSharp和Java
  • 【ThreeJS Basics 06】Camera
  • C++进阶(七)--STL--bitset(位图)的介绍与基本功能模拟实现
  • PyCharm环境配置实战:从搭建到优化的完整指南
  • 观察者模式的C++实现示例
  • Qt:事件
  • 【MySQL】用MySQL二进制包构建docker镜像
  • 基于javaweb的SpringBoot田径运动会管理系统设计和实现(源码+文档+部署讲解)
  • 天津大学02-深度解读DeepSeek:部署、使用、安全【文末附下载链接】
  • leetcode:2965. 找出缺失和重复的数字(python3解法)
  • c盘爆红后,使用diskgenius给C盘无损扩容,操作记录
  • LeetCode Hot100刷题——两数相加(链表)
  • Minix OS的配置 SSH C程序编译
  • git 中 commit 的修改
  • Redis 篇
  • java之http传MultipartFile文件
  • QT day4
  • Kolla-Ansible deploy部署报错 KeyError: \\‘KernelMemory
  • 网站开发设计工程师工作前景/集合竞价口诀背熟6句
  • 建设充值网站多钱/西安百度框架户
  • 四川做网站设计哪家好/灰色关键词怎么做排名
  • 网站注册页面怎么做/谷歌seo招聘
  • 济南网站建设cnwenhui/百度咨询
  • 芜湖网站优化公司/小说推广平台有哪些