题目:容器盛水问题
描述:给定一个整形数组arr,已知其中所有的值都是非负的,将这个数组看作一个容器,请返回容器能装多少水。
示例
输入:[3,1,2,5,2,4]
输出:5
分析:
这道题是2023年3月份华为可信考试2级编程题的原题。题目本身并不难,主要是题目既没有给出示意图,也没有解释一个数组究竟该如何盛水,导致大部分人读完题仍然一头雾水。其实数组盛水是这样的,圆圈就代表水:
把数组看成容器,数组值的大小就是容器的高度。容器能盛多少水,取决于左右两边较低的柱子。我们可以使用双指针算法,从两边向中间靠拢。能盛水的条件就是位置i的数小于其左右两边的数(也就是较低一边的数)。当位置i的数大于较低边时,更新较低边的位置的值。
使用Java代码如下,注意可信考试不能使用idea等编辑器,只能在考试页面手写,需要自己import类。
package com.codernav.demo.hwod;
import java.util.Scanner;
/**
* @title 容器盛水问题
* @Description 给定一个整形数组arr,已知其中所有的值都是非负的,将这个数组看作一个容器,请返回容器能装多少水。
* @Author 开发者导航
* @website https://www.codernav.com
* @date 2023/3/9
*/
public class OdTest42 {
public static void main(String[] args) {
// 输入:[3,1,2,5,2,4] 输出:5
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
String s = sc.nextLine();
String[] sArr = s.split(",");
// 转成int
int[] nums = new int[sArr.length];
for (int i = 0; i < sArr.length; i++) {
nums[i] = Integer.parseInt(sArr[i]);
}
if (nums.length < 1) {
System.out.println("0");
}
// 定义左指针、右指针、左最小值、右最小值
int left = 0;
int right = nums.length - 1;
int leftMaxValue = nums[left];
int rightMaxValue = nums[right];
// 定义盛水总量
int result = 0;
while (left < right) {
// 左边比右边低
if (leftMaxValue < rightMaxValue) {
left++;
// 当前位置大于左边最大值,更新左边最大值
if (nums[left] > leftMaxValue) {
leftMaxValue = nums[left];
} else {
// 当前位置小于左边最大值,就可以盛水了
result += leftMaxValue - nums[left];
}
} else {
right--;
// 当前位置大于右边最大值,更新右边最大值
if (nums[right] > rightMaxValue) {
rightMaxValue = nums[right];
} else {
// 当前位置小于右边最大值,就可以盛水了
result += rightMaxValue - nums[right];
}
}
}
System.out.println(result);
}
}
}
© 版权声明
文章版权归作者所有,未经允许请勿转载。
相关文章
暂无评论...
