【牛客刷题系列】Java篇 | 阿里经典面试题(三)

简介: 【牛客刷题系列】Java篇 | 阿里经典面试题(三)

一、NC128 接雨水问题


描述


给定一个整形数组arr,已知其中所有的值都是非负的,将这个数组看作一个柱子高度图,计算按此排列的柱子,下雨之后能接多少雨水。(数组以外的区域高度视为0)



数据范围:数组长度 0≤n≤2×10……5

,数组中每个值满足 0 < val \le 10^90

,保证返回结果满足 0≤val≤10 9

要求:时间复杂度 O(n)O(n)


示例1


输入:[3,1,2,5,2,4]

返回值:5

说明:数组 [3,1,2,5,2,4] 表示柱子高度图,在这种情况下,可以接 5个单位的雨水,蓝色的为雨水 ,如题面图。


示例2


输入:[4,5,1,3,2]

返回值:2


题解示例:


思路:

这题让求柱子中间能盛多少水,首先可以肯定两边的两个柱子是不能盛水的,只有两边之间的柱子有可能会盛水。最简单的一种方式就是使用3个指针,先找到最高的柱子,用一个指针top指向最高柱子,然后最高柱子左边用两个指针,一个left,一个right(这里的left和right指向柱子的高度)。


如果left大于right,那么肯定是能盛水的,因为left是小于等于最高柱子top的,并且right指向的柱子是在left和最高柱子top之间,根据木桶原理盛水量由最矮的柱子决定,所以盛水是left-right。


如果left不大于right,是不能盛水的,这时候我们要让left等于right。因为right是不能超过最高柱子的,我们增加left的高度,有利于后面计算的时候盛更多的水。


import java.util.*;
public class Solution {
    /**
     * max water
     * @param arr int整型一维数组 the array
     * @return long长整型
     */
      public long maxWater(int[] arr) {
      if (arr.length <= 2)
          return 0;
      //找到最高的柱子的下标
      int max = Integer.MIN_VALUE;
      int maxIndex = -1;
      for (int i = 0; i < arr.length; i++) {
          if (arr[i] > max) {
              max = arr[i];
              maxIndex = i;
          }
      }
      //统计最高柱子左边能接的雨水数量
      int left = arr[0];
      int right = 0;
      long water = 0;
      for (int i = 1; i < maxIndex; i++) {
          right = arr[i];
          if (right > left) {
              left = right;
          } else {
              water += left - right;
          }
      }
      //统计最高柱子右边能接的雨水数量
      right = arr[arr.length - 1];
      for (int i = arr.length - 2; i > maxIndex; i--) {
          left = arr[i];
          if (arr[i] > right) {
              right = left;
          } else {
              water += right - left;
          }
      }
      //返回盛水量
      return water;
  }
}

二、NC44 通配符匹配


描述

请实现支持’?‘and’*'.的通配符模式匹配


‘?’ 可以匹配任何单个字符。

‘*’ 可以匹配任何字符序列(包括空序列)。


返回两个字符串是否匹配

函数声明为:

bool isMatch(const char *s, const char *p)

只有p字符串包含通配符

下面给出一些样例:


isMatch(“aa”,“a”) → false

isMatch(“aa”,“aa”) → true

isMatch(“aaa”,“aa”) → false

isMatch(“aa”, “") → true

isMatch(“aa”, "a”) → true

isMatch(“ab”, “?") → true

isMatch(“aab”, "da*b”) → false


数据范围:字符串长度满足10000≤n≤1000

进阶:空间复杂度 O(1)O(1),时间复杂度 O(n)O(n)


示例1


输入:“ab”,“?*”

返回值:true


示例2


输入:“ab”,“*”

返回值:true


题解示例:

贪心算法:

如果i和j标记的字符正好相等或者j字符是’?'匹配成功,则"移除"i和j元素,即自增i、j。

否则如果j字符是✳(*号)依然可以匹配成功,则用istart和jstart分别标记i元素和j元素之后自增j。

否则如果istart>-1说明之前匹配过✳,因为✳可以匹配多个字符,所以这里要再次利用这个最近匹配过的✳匹配更多的字符,移动i标记istart的下一个字符,再让istart重新标记i元素同时移动j标记jstart的下一个字符。

上述三种情况都不满足,则匹配失败,返回false。

最后当s中的字符都判断完毕,则认为s为空,此时需要p为空或者p中只剩下星号的时候,才能成功匹配。


public class Solution {
    public boolean isMatch(String s, String p) {
          if (p==null||p.isEmpty())return s==null||s.isEmpty();
    int i=0,j=0,istart=-1,jstart=-1,slen=s.length(),plen=p.length();
    //判断s的所有字符是否匹配
    while (i<slen){
        //三种匹配成功情况以及匹配失败返回false
        if (j<plen&&(s.charAt(i)==p.charAt(j)||p.charAt(j)=='?')){
            i++;
            j++;
        }else if (j<plen&&p.charAt(j)=='*'){
            istart=i;
            jstart=j++;
        }else if (istart>-1){
            i=++istart;
            j=jstart+1;
        }else {
            return false;
        }
    }
    //s中的字符都判断完毕,则认为s为空,此时需要p为空或者p中只剩下星号的时候,才能成功匹配。
    while (j<plen&&p.charAt(j)=='*')j++;
    return j==plen;
    }
}



目录
相关文章
|
23天前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
61 2
|
11天前
|
Java 程序员
Java社招面试题:& 和 && 的区别,HR的套路险些让我翻车!
小米,29岁程序员,分享了一次面试经历,详细解析了Java中&和&&的区别及应用场景,展示了扎实的基础知识和良好的应变能力,最终成功获得Offer。
35 14
|
28天前
|
存储 算法 Java
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
本文详解自旋锁的概念、优缺点、使用场景及Java实现。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
|
1月前
|
存储 缓存 Oracle
Java I/O流面试之道
NIO的出现在于提高IO的速度,它相比传统的输入/输出流速度更快。NIO通过管道Channel和缓冲器Buffer来处理数据,可以把管道当成一个矿藏,缓冲器就是矿藏里的卡车。程序通过管道里的缓冲器进行数据交互,而不直接处理数据。程序要么从缓冲器获取数据,要么输入数据到缓冲器。
Java I/O流面试之道
|
24天前
|
SQL 关系型数据库 MySQL
阿里面试:1000万级大表, 如何 加索引?
45岁老架构师尼恩在其读者交流群中分享了如何在生产环境中给大表加索引的方法。文章详细介绍了两种索引构建方式:在线模式(Online DDL)和离线模式(Offline DDL),并深入探讨了 MySQL 5.6.7 之前的“影子策略”和 pt-online-schema-change 方案,以及 MySQL 5.6.7 之后的内部 Online DDL 特性。通过这些方法,可以有效地减少 DDL 操作对业务的影响,确保数据的一致性和完整性。尼恩还提供了大量面试题和解决方案,帮助读者在面试中充分展示技术实力。
|
29天前
|
存储 缓存 Java
大厂面试必看!Java基本数据类型和包装类的那些坑
本文介绍了Java中的基本数据类型和包装类,包括整数类型、浮点数类型、字符类型和布尔类型。详细讲解了每种类型的特性和应用场景,并探讨了包装类的引入原因、装箱与拆箱机制以及缓存机制。最后总结了面试中常见的相关考点,帮助读者更好地理解和应对面试中的问题。
52 4
|
1月前
|
存储 Java 程序员
Java基础的灵魂——Object类方法详解(社招面试不踩坑)
本文介绍了Java中`Object`类的几个重要方法,包括`toString`、`equals`、`hashCode`、`finalize`、`clone`、`getClass`、`notify`和`wait`。这些方法是面试中的常考点,掌握它们有助于理解Java对象的行为和实现多线程编程。作者通过具体示例和应用场景,详细解析了每个方法的作用和重写技巧,帮助读者更好地应对面试和技术开发。
86 4
|
1月前
|
算法 Java
JAVA 二叉树面试题
JAVA 二叉树面试题
17 0
|
20天前
|
Java 开发者
Java多线程编程中的常见误区与最佳实践####
本文深入剖析了Java多线程编程中开发者常遇到的几个典型误区,如对`start()`与`run()`方法的混淆使用、忽视线程安全问题、错误处理未同步的共享变量等,并针对这些问题提出了具体的解决方案和最佳实践。通过实例代码对比,直观展示了正确与错误的实现方式,旨在帮助读者构建更加健壮、高效的多线程应用程序。 ####
|
11天前
|
缓存 Java 开发者
Java多线程编程的陷阱与最佳实践####
本文深入探讨了Java多线程编程中常见的陷阱,如竞态条件、死锁和内存一致性错误,并提供了实用的避免策略。通过分析典型错误案例,本文旨在帮助开发者更好地理解和掌握多线程环境下的编程技巧,从而提升并发程序的稳定性和性能。 ####