纯新手,用for循环2小时攻破所谓的“接雨水”二维+三维甚至推广到更高维度

 这是题目

,很容易就看出接的雨水的形状是倒三角类型的,我觉得和for循环打印三角形差不多;

只是这个图像有三角形和烟囱形的形式,反正最上面雨水那一层总是比下面那一层的多。

浅浅画一个

以下是这道题的代码,虽然做出来了但是没提交leetcode,因为不知道咋写那种输入



import java.lang.*;
import java.util.Scanner;

/**
 * 0 0 1 0 2 1 0 1 3 2 1 2 1 0
 * 在n个柱子旁边加上地平线“0”,那么数组为a[n-1]和a[n+1]就为0
 * 用a[i] < a[i + n] && a[i] < a[i - 1]找到最小值,(n = 1、2、3...) ,然后count+1
 * 找到a[i-1]与a[i+n]之间的数,随着n的增大,里面的值就越多,我用for循环去count++;
 * 然后定义一个变量add(称为count之前的值),如果count一直在增加,那么就不扩大n,即区间的范围。
 * 当count==add,那么就增大区间,即n++
 * 
 * 关键代码:
 *         for (int n = 1;n<=size-2;){
 *             int add = count;
 *             for(int i = 1;i < size-1;i++){
 *                 if (i + n <size -1) {
 *                     if (a[i] < a[i + n] && a[i] < a[i - 1]) {
 *                         for (int j = 0; j < n; j++) {
 *                             a[i + j]++;
 *                             count++;
 *                         }
 *                     }
 *                 }
 *             }if( count == add){n++;}
 *         }
 * 
 * ---------------------------------------------------------------------------
 * size是你加了地平线的数组长度,size = n+2
 */
public class asd {
    public static void main(String[] args) {
        int count = 0;  //计算能接多少雨水
        Scanner s = new Scanner(System.in);
        System.out.println("输入你的数组长度为:");//size-2 = n
        final int size = s.nextInt();
        if (size <= 4){
            System.out.println("一共接了"+count+"滴水");
            System.exit(0);
        }
        int a[] = new int[size];
        a[0] = 0;
        for (int i = 1;i<size-1;i++){
            int x = s.nextInt();
            a[i] = x;
        }
        a[size-1] = 0;
        //打印现在的数组情况
        System.out.println("开始的数组情况为:");
        for (int i = 0;i<size;i++){
            System.out.print(a[i]+"\t");
        }


        //开始解题
        for (int n = 1;n<=size-2;){
            int add = count;
            for(int i = 1;i < size-1;i++){
                if (i + n <size -1) {
                    if (a[i] < a[i + n] && a[i] < a[i - 1]) {
                        for (int j = 0; j < n; j++) {
                            a[i + j]++;
                            count++;
                        }
                    }
                }
            }if( count == add){n++;}
        }



        //打印接水后的数组情况
        System.out.println();
        System.out.println("结束的数组情况为:");
        for (int i = 0;i<size;i++){
            System.out.print(a[i]+"\t");
        }
        System.out.println();
        System.out.println("一共接了"+count+"滴水");
    }
}

【没错,我猜你也想到了吧】

这种不规则形状的水咋办?先找底部的起点?然后走迷宫走出来?

那这样的呢?请问阁下该如何应对?稍微动动脑筋,

刚刚的 height = [0,1,0,2,1,0,1,3,2,1,2,1] 就当只是个一维的。
而我出的这个是二维的,可以表示成这样[

[0,0,0,0,0,0,1,0,0,0,0,0],

[0,0,0,0,1,0,1,1,1,0,0,0],

[0,0,0,0,1,0,1,1,1,1,0,1],

[1,1,1,0,1,0,1,0,0,0,0,1],

[1,0,0,0,1,0,1,1,0,0,0,1],

[1,1,0,0,1,0,0,0,1,0,1,1]]

那这就只不过是多了几行一维数组而已,只需再加个for循环而已,一行一行的判断,把1之间的0都变成1,再count就行了。

最开始那道接雨水的题也可以用这种方法做,只需要把一维变成二维,再把二维变成一维就行了

下面是代码

package com.newton.test;

import java.lang.*;
import java.util.Scanner;

/**
 * 默认雨水的高度小于9,(可以自行更改的)
 * 关键代码:
 * for (int n = 1;n<=size-2;){
 *             int add = count;
 *             for (int j = 0;j<9;j++) {
 *                 for (int i = 1; i < size - 1; i++) {
 *                     if (i + n < size - 1) {
 *                         if (a_copy[i][j] < a_copy[i + n][j] && a_copy[i][j] < a_copy[i - 1][j]) {
 *                             for (int m = 0; m < n; m++) {
 *                                 a_copy[i + m][j]++;
 *                                 count++;
 *                             }
 *                         }
 *                     }
 *                 }
 *             }if( count == add){n++;}
 *         }
 */
public class RainyDay_1_5 {
    public static void main(String[] args) {
        int count = 0;  //计算能接多少雨水
        Scanner s = new Scanner(System.in);
        System.out.println("输入你的数组长度为:");//size-2 = n
        final int size = s.nextInt();
        int a_copy[][] = new int[size][9];  //9代表的是雨水的高度的最大值
        if (size <= 4){
            System.out.println("一共接了"+count+"滴水");
            System.exit(0);
        }
        int b[] = new int[size];
        int a[] = new int[size];
        a[0] = 0;
        for (int i = 1;i<size-1;i++){
            int x = s.nextInt();
            a[i] = x;
        }
        a[size-1] = 0;
        //打印现在的一维数组情况
        System.out.println("开始的数组情况为:");
        for (int i = 0;i<size;i++){
            System.out.print(a[i]+"\t");
        }
        System.out.println();
        System.out.println("将一维数组变为二维...");
        for (int i = 0;i<size;i++){
            for (int j=0;j<a[i];j++){
                a_copy[i][j] = 1;
            }
        }
        //打印现在的二维数组情况
        System.out.println("现在的二维数组情况为:");
        for (int j = 0;j<9;j++){
            for (int i = 0;i<size;i++){
                System.out.print(a_copy[i][j]+"\t");
            }
            System.out.println();
        }

        //开始解题
        for (int n = 1;n<=size-2;){
            int add = count;
            for (int j = 0;j<9;j++) {
                for (int i = 1; i < size - 1; i++) {
                    if (i + n < size - 1) {
                        if (a_copy[i][j] < a_copy[i + n][j] && a_copy[i][j] < a_copy[i - 1][j]) {
                            for (int m = 0; m < n; m++) {
                                a_copy[i + m][j]++;
                                count++;
                            }
                        }
                    }
                }
            }if( count == add){n++;}
        }

        //打印现在的二维数组情况
        System.out.println("现在的二维数组情况为:");
        for (int j = 0;j<9;j++){
            for (int i = 0;i<size;i++){
                System.out.print(a_copy[i][j]+"\t");
            }
            System.out.println();
        }
        System.out.println("将二维降为一维");
        //将二维数组降为一维
        int count_2;
        for (int j = 0;j<9;j++){
            for (int i = 0;i<size;i++){
                if (a_copy[i][j] == 1){
                    b[i]++;
                }
            }
        }

        //打印接水后的数组情况
        System.out.println();
        System.out.println("结束的数组情况为:");
        for (int i = 0;i<size;i++){
            System.out.print(b[i]+"\t");
        }
        System.out.println();
        System.out.println("一共接了"+count+"滴水");
    }
}


运行一下,

        好了,接下来是三维的接雨水了,题目是这样的

这样的

大家别被吓到了哦,草履虫都知道被子能装多少水得从杯口俯视着看,你看杯子侧面那只是凭经验猜测能装多少水。

那么,这一道题也还是二维的。刚刚第一题是从左往右判断a[i] < a[i + n] && a[i] < a[i - 1]。

这一题就得增加一个从上往下判断了。

解释在代码里面也有,自己看吧



import java.lang.*;
import java.util.Scanner;

/**
 * heightMap = [[1,4,3,1,3,2],[3,2,1,3,2,4],[2,3,3,2,3,1]]
 * length = 8 ;width = 5
 * 1 4 3 1 3 2                       1  4   3 "3" 3  2     |                 1  4   3 "3" 3  2
 * 3 2 1 3 2 4   ---length--->7di    3 "3" "3" 3 "3" 4     | ---width-->0di  3 "3" "3" 3 "3" 4
 * 2 3 3 2 3 1                       2  3   3 "3" 3  1     |                 2  3   3 "3" 3  1
 * ——————————————————————————————————————————————————————————
 * 1 4 3 1 3 2                   1  4   3  1  3  2          |                 1  4   3 "3" 3  2
 * 3 2 1 3 2 4  ----width-->4di  3 "3" "3" 3 "3" 4          |---length-->3di  3 "3" "3" 3 "3" 4
 * 2 3 3 2 3 1                   2  3  3   2  3  1          |                 2  3   3 "3" 3  1
 * ——————————————————————————————————————————————————————————
 * 我们分别看 length的 和width的 
 * 很容易就看出,length和width重叠的那一部分才是真正该count++的地方
 *        1 4 3 1 3 2             1  4   3  1  3  2
 * 即为    3 2 1 3 2 4 ------>4di  3 "3" "3" 3 "3" 4
 *        2 3 3 2 3 1             2  3  3   2  3  1
 *
 * 例子1:length = 7 ,width = 7
 *  3 3 3 3 3
 *  3 2 2 2 3
 *  3 2 1 2 3
 *  3 2 2 2 3
 *  3 3 3 3 3
 *  例子2:length = 13, width = 13
 *  9 9 9 9 9 9 9 9 9 9 9
 *  9 8 8 8 8 8 8 8 8 8 9
 *  9 8 7 7 7 7 7 7 7 8 9
 *  9 8 7 6 6 6 6 6 7 8 9
 *  9 8 7 6 5 5 5 6 7 8 9
 *  9 8 7 6 5 0 5 6 7 8 9
 *  9 8 7 6 5 5 5 6 7 8 9
 *  9 8 7 6 5 5 5 6 7 8 9
 *  9 8 7 7 7 7 7 7 7 8 9
 *  9 8 8 8 8 8 8 8 8 8 9
 *  9 9 9 9 9 9 9 9 9 9 9
 *
 */

public class RainyDay_2 {
    public static void main(String[] args) {
        double count = 0;  //计算能接多少雨水
        Scanner s = new Scanner(System.in);
        System.out.println("输入你的数组长度为:");//length-2 = n
        final int length = s.nextInt();
        System.out.println("输入你的数组宽度为:");//width-2 = n
        final int width = s.nextInt();

        double a_copy[][] = new double[length][width];
        double moment[][] = new double[length][width];  // 全为0的暂时数组
        for (int j = 0;j<width;j++){
            for (int i = 0;i<length;i++){
                moment[i][j] = 0;
            }
        }
        if (length <= 4 && width <=4){
            System.out.println("一共接了"+count+"滴水");
            System.exit(0);
        }
        //补齐二维数组左侧的“0” ,其实数组自带补“0”
        double a[][] = new double[length][width];
        for (int j = 1;j<width-1;j++){
            a[0][j] = 0;
        }
        //输入二维数组
        for (int j = 1;j<width-1;j++){
            for (int i = 1;i<length-1;i++){
                int x = s.nextInt();
                a[i][j] = x;
            }
        }
        //补齐二维数组右侧的“0”,其实数组自带补“0”
        for (int j = 1;j<width-1;j++){
            a[length-1][j] = 0;
        }
        //打印现在的数组情况
        System.out.println("开始的数组情况为:");
        for (int j = 1;j<width-1;j++){
            for (int i = 1;i<length-1;i++){
                a_copy[i][j] = a[i][j];
                System.out.print((int)a[i][j]+"\t");
            }
            System.out.println();
        }

        //开始解题
        for (int n = 1;n<=length-2;){
            count = (int)count;
            double add = count;
            for (int j = 1;j<width-1;j++) {            //从第一排到第二排依次检测,横向的length i
                for (int i = 1; i < length - 1; i++) {
                    if (i + n < length) {
                        if (a[i][j] < a[i + n][j] && a[i][j] < a[i - 1][j]) {
                            for (int m = 0; m < n; m++) {
                                a[i + m][j] ++;
                                moment[i+m][j] ++;         //一个临时的moment[i][j]数组,可以暂时存放增加的痕迹
                                count = count + 0.001;  //count不能加一,但是需要微小变化
                            }
                        }
                    }
                }
            }if (count == add) {
                n++;
            }
        }
        for (int n = 1;n<=width-2;){
            double add = count;
            for (int j = 1;j<width-1; j++) {      //从第一列到第二列依次检测 纵向的width j
                for (int i = 1; i < length - 1; i++) {
                    if (j + n < width) {               //用新的a_copy来增加,如有之前增加的痕迹再增加count
                        if (a_copy[i][j] < a_copy[i][j + n] && a_copy[i][j] < a_copy[i][j - 1] && (moment[i][j] > 0)) {
                            for (int m = 0; m < n; m++) {
                                a_copy[i][j + m] = a_copy[i][j + m] + 1;
                                count = count + 1;
                            }
                        }
                    }
                }
            }if (count == add) {
                n++;
            }
        }
        //打印接水后的数组情况
        System.out.println();
        System.out.println("结束的数组情况为:");
        for (int j = 1;j<width-1;j++){
            for (int i = 1;i<length-1;i++){
                System.out.print((int)a_copy[i][j]+"\t");
            }
            System.out.println();
        }
        System.out.println();
        System.out.println("一共接了"+(int)count+"滴水");
    }
}

运行一下,怕你们不信

至于推广到多维度的,比如说四维的东西能接多少雨水.....也许只是多一个for循环,感兴趣的话可以尝试去思考思考,顺便思考一下四维的杯子长啥样吧哈哈哈

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值