算法题
经过三道题,近乎两小时的洗礼。
我似乎明白了双指针的精髓。
双指针,双指针,双:一定会出现两者的相互关系。
而借助两者关系就能让两者相互“运动”,从而可以尽量把 O(n^2^) 的时间缩短至 O(n)。
盛最多水的容器
给定一个 heights 数组,索引代表 x 轴上的点,每一个值代表这个点的高度(y)。
尝试找到两个点之间构成的容器(矩形),能形成的最大面积。
关键点:木桶效应,容量是由最短的边决定的。
解题思路:
- 面积由 x, y 两者决定,因此首先定义双指针指向左右边界,使得 x 最大。
- 其次就到了遍历求解过程了:如何让 x 缩减的同时,y 能尽量增大。
- 假设选定了两条边分为位于 a, b 点,距离为 t,且 a < b;
- 如果移动 b,最大面积绝对不会超过 a * t,所以关键在于最短边;
- 只要每次移动短的那一边,就能尽可能让结果增大,以此减少遍历次数。
- 同时由于容器两边肯定要不能重合或反着计算对称的结果,应确保 a < b;
再优化
再遍历次数无法减少的情况下,可以对计算次数进行简化。
记录最短边,只要移动过后的值还 <= 最短边,就一直移动无需计算。
三数之和
给定一个 nums 数组,要求找出位置互不相同的三个数,使其满足 i + j + k = 0。
解题思路:
首先为了避免三个在三三遍历时出现一个尾,一个头重复使用的情况,应对数组进行排序,然后有序遍历。
找出两者关系,三个数,两者关系???
i + j + k = 0 可以转化为 j + k = -i
将 i, j, k 分别看做三个数,普通思路是直接三层遍历 O(n^3^),
但是当第一层遍历时,i 的值在某一个刻是确定的。
因此第 2 和 3 层遍历是有关系的。
要想保证 i 不变,需要一层增加,一层减少。
由于数组时有序且递增的,
只需要在第二层递增遍历时,同时让第三层递减遍历即可,这样就减少了一层时间复杂度。
Java 八股
Java的特点
面向对象、平台无关、多线程、可靠性、安全、高效。
Java:“编译与解释并存”
java代码 -> 字节码 -> 机器码
基本类型和包装类型的区别
- 用途
- 存储方式
- 占用空间
- 默认值
- 比较方式
包装类型的缓存机制
new 和 自动装箱
包装类的装箱和拆箱的本质
valueOf intValue
如何解决浮点数运算精度丢失问题
BigDecimal 字符数组
超过 long 长度的整型该如何表示
BigInteger
成员变量和局部变量的区别
语法形式:访问修饰符,static
存储方式:堆,栈
生存时间:实例创建,局部作用域
默认值
为什么成员变量有默认值
字符型常量和字符串常量的区别?
表示形式:
含义:
内存大小:
重写父类方法的要求
返回值类型,抛出异常,访问修饰符(向上转型)
可变长参数 Java5
声明位置?
遇上方法重载?优先级低
面向过程性能比面向对象高?
c / C++, Java?
面向对象三大特征
封装
集成
多态
浅拷贝、深拷贝、引用拷贝
一层
完全
地址
==与equals方法的区别
Object默认的equals
为什么重写equals必须重写hashcode方法?
因为相等的对象hashcode必须一致,否则hashmap会出现相同的key值的情况