刷算法,这些api不可不知!
大家好,我是老三,最近在刷算法,发现有些api记得不熟,所以整理了一波,如果你也在刷题,赶紧收藏
吧!
集合
在刷题中,各种数据结构是我们常常用到的,例如栈实现迭代、哈希存储键值对等等,我们来看看常用集合和相关api。
类/接口 | 描述 | 方法 |
---|---|---|
String | 字符串 | charAt toCharArray split substring indexOf lastIndexOf replace length |
List | 列表 | add remove get size subList |
Stack | 栈 | push pop peek isEmpty size |
Queue | 队列 | offer poll peek isEmpty size |
Deque | 双向队列 | offerFirst offerLast pollFirst pollLast peekFirst peekLast isEmpty size |
PriorityQueue | 优先队列 | offer poll peek isEmpty size |
Set | add remove contains isEmpty size first(TreeSet) last(TreeSet) | |
Map | put get getOrDefault containsKey containsValue keySet values isEmpty size |
数组
数组就不用多说什么了,大家最熟悉的数据结构。
Arrays
Arrays是比较常用的数组工具类,可以完成排序、拷贝等功能。
- 从小到大排序:Arrays.sort(int[] arr)
Arrays.sort(int[] arr, int fromIndex, int toIndex, 比较器); //一定是需要泛型
Arrays.sort(arr, (o1, o2) -> o2 - o1); //数组全部 从大到小排序 跟Collections.sort()一样
Arrays.sort(arr, 0, 3, (o1, o2) -> o2 - o1); //从大到小排序,只排序[0, 3)
- 拷贝:Array.copyOf
int[] a = new int[5];
int[] newA = Array.copyOf(a, 5);
列表
列表主要有两种实现,分别是顺序表和链表。
顺序表本质是一个可以动态扩容的数组,在Java中的实现是ArrayList
。
链表是一个双向链表,Java中链表的实现为LinkedList
。LinkedList
在Java中可谓是非常强大的一个集合类,它还可以作为双向队列、栈来使用。
注意,ArrayList的扩容需要将旧的数组的元素复制到新的数组,时间复杂度为O(n)。
基本方法
- 构造
List<Integer> array = new ArrayList<>(); // 顺序表
// Set<Integer> a = new HashSet....
List<Integer> b = new ArrayList<>(a); //接受一个集合容器
- get
get(int index) // 返回元素位置在index的元素e --- array O(1), list O(n)
size
size() // 返回数组/链表长度 --- O(1)
- add
add(E e) // 在尾部添加一个元素e --- O(1)
add(int index, E e) // 在index位置插一个元素e --- O(n)
- remove
.remove(int index) // 删除位于index的元素,并返回删除元素e --- 删除最后元素为O(1), 其余为O(n)
//删除最后元素 list.remove(list.size() - 1);
- subList
.subList(int from, int to) // 相当于返回原数组的一个片段,但不要对其进行改动,改动会影响原数组 --- O(1)
// List<Integer> list, 对原来的list和返回的list做的“非结构性修改”(non-structural changes),
//都会影响到彼此对方. 如果你在调用了sublist返回了子list之后,如果修改了原list的大小,那么之前产生的子list将会失效,变得不可使用
集合工具
Collections是集合工具类,提供了一些操作集合的方法。
- 排序
Collections.sort(list); 从小到大排序
Collections.sort(list, (o1, o2) -> o2 - o1); 从大到小排序, 第二个参数为一个比较器
两种实现,ArrayList利于查找,LinkedList利于增删。
大概对比如下:
操作 | ArrayList | LinkedList |
---|---|---|
get(int index) | O(1) | O(n),平均 n / 4步 |
add(E element) | 最坏情况(扩容)O(n) ,平均O(1) | O(1) |
add(int index, E element) | O(n) ,平均n / 2步 | O(n),平均 n / 4步 |
remove(int index) | O(n) 平均n /2步 | O(n),平均 n / 4步 |
栈
Java中定义了Stack
接口,实现类是Vector
。Vector
是一个祖传集合类,不推荐使用。
那应该用什么呢?
Deque
接口实现了完善堆栈操作集合,它有一个我们熟悉的实现类LinkedList
。
- 构造
Deque<Integer> stack=new LinkedList<>();
- push
push(E e); // 入栈元素e, 返回值为元素e --- O(1)
- pop
.pop(); // 出栈一个元素,返回出栈元素e --- O(1)
- peek
peek(); // 查看栈顶元素, 返回值为栈顶元素e --- O(1)
- isEmpty
isEmpty() // 若栈空返回true, 否则返回false --- O(1)
- size
size() // 返回栈中元素个数 --- O(1)
队列
队列s是一种先进先出的结构,在Java中的接口定义是Queue
,具体实现还是我们的老朋友LinkedList
。
- 构造
Queue<Integer> q = new LinkedList<>();
- offer
offer(E e); // 队尾加入元素e。 若成功入队返回值true,否则返回false --- O(1)
- poll
poll(); // 出队头,返回出队元素e --- O(1)
- peek
peek(); // 查看队头元素, 返回值队首元素e --- O(1)
- isEmpty
isEmpty() // 若队空返回true, 否则返回false --- O(1)
- size
size() // 返回队中元素个数 --- O(1)
双向队列
Queue
有一个子接口Dueue
,即双向队列,和单向队列不同,它的出队入队可以从两个方向。
- 构造
Dueue<Integer> q = new LinkedList<>();
- offFirst
offFirst(Object e) // 将指定元素添加到双端队列的头部 --- O(1)
- offLast
offLast(Object e) //将指定元素添加到双端队列的尾部 --- O(1)
- pollFirst
pollFirst() //获取并删除双端队列的第一个元素 --- O(1)
- pollLast
pollLast() //获取并删除双端队列的最后一个元素 --- O(1)
- peekFirst
peekFirst() //获取但不删除双端队列的第一个元素 --- O(1)
- peekLast
peekLast() //获取但不删除双端队列的最后一个元素 --- O(1)
优先队列
优先队列是一种比较特殊的队列,保存队列元素的顺序不是按照元素添加的顺序来保存的,而是在添加元素的时候对元素的大小排序后再保存。
所以在队头的元素不是按照先后顺序,而是按照大小顺序。
在Java中的实现是PriorityQueue
,底层是一棵树, 以小根堆为例。对于任意结点来说,该节点的值比其左右孩子的值都要小。 (就是最上面的结点最小)。 大根堆类似,最上面结点最大
- 构造
- 小根堆
Queue<Integer> minH = new PriorityQueue<>(); // 小根堆,默认大小为11 相当于 new PriorityQueue<>(11)
Queue<Integer> minH = new PriorityQueue<>(100); // 定义一个默认容量有100的小根堆。在当中增加元素会扩容,只是开始指定大小。不是size,是capacity
- 大根堆
Queue<Integer> maxH = new PriorityQueue<>((i1, i2) -> i2 - i1); // 大根堆,默认大小为11 相当于 new PriorityQueue<>(11, (i1, i2) -> i2 - i1)
Queue<Integer> maxH = new PriorityQueue<>(100, (i1, i2) -> i2 - i1); // 定义一个默认容量有100的大根堆。在当中增加元素会扩容,只是开始指定大小
- offer
offer(E e); // 在堆中加入元素e,并调整堆。若成功入堆返回值true,否则返回false --- O(logN)
- poll
poll(); // 弹出堆顶元素,并重新调整堆,返回出队元素e --- O(logN)
- peek
peek(); // 查看堆顶元素, 返回值堆顶元素e --- O(1)
散列表
散列表示一种<key,value>型的数据结构,在Java中的实现是HashMap
。
- 构造
Map<Characters, Integer> map = new HashMap<>();
- put
put(K key, V value); // 在Map中加入键值对<key, value>。返回value值。如果Map中有key,则replace旧的value --- O(1)
- get
get(K key); // 返回Map中key对应的value。若Map中没有该key,则返回null --- O(1)
- getOrDefault
getOrDefault(K key, V defaultValue); // 返回Map中key对应的value。若Map中没有该key,则返回defaultValue --- O(1)
// For example:
// Map<Character, Integer> map = new HashMap<>();
// if (...) // 如果发现k,则k在Map中的值加1。没一开始没有k,则从0开始加1。(相当于给了key在Map中的一个初试值)
map.put('k', map.getOrDefault('k', 0) + 1);
- containsKey
containsKey(Key key); // 在Map中若存在key,则返回true,否则返回false --- O(1)
get(x) == null // 可以代替改用法
- keySet
keySet(); // 返回一个Set,这个Set中包含Map中所有的Key --- O(1)
// For example:
// We want to get all keys in Map
// Map<Character, Integer> map = new HashMap<>();
for (Character key : map.keySet()) {
// Operate with each key
}
- values
values(); // 返回一个Collection<v>,里面全是对应的每一个value --- O(1)
// For example:
// We want to get all values in Map
// Map<Character, Integer> map = new HashMap<>();
for (Integer value : map.values()) {
// Operate with each values
}
- isEmpty
isEmpty() // 若Map为空返回true, 否则返回false --- O(1)
- size
.size() // 返回Map中中键值对<K, V>的个数 --- O(1)
Set
Set是一种没有重复元素的集合,常用的实现是HashSet
。
- 构造
Set<Integer> set = new HashSet<>();
List<Integer> list = new ArrayList<>....;
Set<Integer> set = new HashSet<>(list);
- add
.add(E e); // 在集合中添加元素E e, 若成功添加则返回true,若集合中有元素e则返回false --- O(1)
- remove
remove(E e); // 在集合中删除元素e,若删除成功返回true;若集合中没有元素e,返回false --- O(1)
- contains
contains(E e); // 若存在元素e,则返回true,否则返回false --- O(1)
- isEmpty
isEmpty() // 若集合为空返回true, 否则返回false --- O(1)
- size
size() // 返回集合中中元素个数 --- O(1)
- first
first() // 返回集合里的最小值(若给了比较器从大到小则是返回最大值)
- last
last() // 返回集合里的最大值(若给了比较器从大到小则是返回最小值)
字符串
String
不可变量(相当于只读final修饰),每个位置元素是个char。
- 初始化
字符串复制初始化
String s = ``"abc"``;
基于另外一个字符串
// s = "abc"``String s2 = ``new` `String(s);
基于char[]
// s = "abc";
// char[] c = s.toCharArray();
String s3 = new String(c);
// 可以偏移
// public String(char value[], int offset, int count)
String s4 = new String(c, 1, 2); // [offset, offset + count) [)
// 把char[] 变成字符串
char[] ch = {'a', 'b', 'c'};
String.valueOf(ch);
- charAt
charAt(int index); // 返回index位置的char --- O(1)
- length
length(); // 返回字符串长度 --- O(1)
- substring
substring(int beginIndex, int endIndex); // 返回字符片段[beginIndex, endIndex) --- O(n)
substring(int beginIndex); // 返回字符片段[beginIndex, end_of_String) 就是从beginIndex开始后面的 ---- O(n)
- indexOf
indexOf(String str) // 返回str第一个出现的位置(int),没找到则返回-1。 --- O(m * n) m为原串长度, n为str长度
// (假如要找一个字符char c,str可以表示成String.valueOf(c),然后作为参数传进去.
s.indexOf(String str, int fromIndex); // 同上,但从fromIndex开始找 --- O(m * n)
- lastIndexOf
lastIndexOf(String str); // 返回str最后出现的位置(int),没找到则返回-1。 --- O(m * n) m为原串长度, n为str长度
// (假如要找一个字符char c,str可以表示成String.valueOf(c),然后作为参数传进去.
lastIndexOf(String str, int fromIndex); // 同上,
//但从fromIndex开始从后往前找 [0 <- fromIndex] --- O(m * n)
- replace
replace(char oldChar, char newChar); // 返回一个新字符串String,其oldChar全部变成newChar --- O(n)
- toCharArray
toCharArray(); // 返回char[] 数组。 把String编程字符数组 --- O(n)
- trim
trim(); // 返回去除前后空格的新字符串 --- O(n)
- split
split(String regex); // 返回 String[],以regex(正则表达式)分隔好的字符换数组。 ---- O(n)
// For example
// 从非"/"算起 若"/a/c" -> 会变成"" "a" "c"
String[] date = str.split("/"); // date[0]:1995 date[1]:12 date[2]:18 --- O(n)
- toLowerCase, toUpperCase
s = s.toLowerCase(); // 返回一个新的字符串全部转成小写 --- O(n)
s = s.toUpperCase(); // 返回一个新的字符串全部转成大写 --- O(n)
StringBuilder
由于String是所谓的不可变类,使用 str+
这种形式拼接字符串实际上,是JVM帮助循环创建StringBuilder来拼接,所以拼接字符串最好用StringBuilder。
- 构造
StringBuilder sb = new StringBuilder();
- charAt
charAt(int index); // 返回index位置的char --- O(1)
- length
length(); // 返回缓冲字符串长度 --- O(1)
- apped
append(String str) // 拼接字符串 --- O(n)
- toString
toString(); // 返回一个与构建起或缓冲器内容相同的字符串 --- O(n)
数学
最大最小值
在一些题目里,需要用到最大,最小值,Java中各个数据类型的最大最小值定义如下:
fmax = Float.MAX_VALUE;
fmin = Float.MIN_VALUE;
dmax = Double.MAX_VALUE;
dmin = Double.MIN_VALUE;
bmax = Byte.MAX_VALUE;
bmin = Byte.MIN_VALUE;
cmax = Character.MAX_VALUE;
cmin = Character.MIN_VALUE;
shmax = Short.MAX_VALUE;
shmin = Short.MIN_VALUE;
imax = Integer.MAX_VALUE;
imin = Integer.MIN_VALUE;
lmax = Long.MAX_VALUE;
lmin = Long.MIN_VALUE;
Math
- max
Math.max(long a, long b); //返回两个参数中较大的值
- sqrt
Math.sqrt(double a); //求参数的算术平方根
- abs
Math.abs(double a); //返回一个类型和参数类型一致的绝对值
- pow
Math.pow(double a, double b); //返回第一个参数的第二个参数次方。
- ceil
Math.ceil(double x); //向上取整
- floor
Math.floor(double x); //向下取整
- round
Math.round(double x); //四舍五入
"简单的事情重复做,重复的事情认真做,认真的事情有创造性地做!"——
我是
三分恶
,一个能文能武的全栈开发。
点赞
、关注
不迷路,咱们下期见!
参考:
[1].Java刷题常用API
[2].Java 刷题集合类
刷算法,这些api不可不知!的更多相关文章
- c++刷算法的好处
写再最前面:摘录于柳神的笔记 在已经学习过C语⾔的前提下,学习C++并使⽤它刷算法的学习成本⾮常低-只需要⼏个⼩时就可 以学会- C++向下兼容C,C语⾔⾥⾯的语法完全可以在C++⽂件中运⾏,所以学习 ...
- 关于 Java Collections API 您不知道的 5 件事,第 1 部分
定制和扩展 Java Collections Java™ Collections API 远不止是数组的替代品,虽然一开始这样用也不错.Ted Neward 提供了关于用 Collections 做更 ...
- 关于 Java Collections API 您不知道的 5 件事--转
第 1 部分 http://www.ibm.com/developerworks/cn/java/j-5things2.html 对于很多 Java 开发人员来说,Java Collections A ...
- java入门学习(3)—循环,选择,基础算法,API概念
1.顺序结构:也就是顺着程序的前后关系,依次执行.2.选择分支:利用if..else , / switch(){case [ 这个必须是常量]:}; / if..else if….. ….else.. ...
- 关于JavaScripting API您不知道的5件事
现在,许多 Java 开发人员都喜欢在 Java 平台中使用脚本语言,但是使用编译到 Java 字节码中的动态语言有时是不可行的.在某些情况中,直接编写一个 Java 应用程序的脚本 部分 或者在一个 ...
- 令牌桶算法实现API限流
令牌桶算法( Token Bucket )和 Leaky Bucket 效果一样但方向相反的算法,更加容易理解.随着时间流逝,系统会按恒定 1/QPS 时间间隔(如果 QPS=100 ,则间隔是 10 ...
- 关于Java Collections API您不知道的5件事,第2部分
注意可变对象 java.util 中的 Collections 类旨在通过取代数组提高 Java 性能.如您在 第 1 部分 中了解到的,它们也是多变的,能够以各种方 式定制和扩展,帮助实现优质.简洁 ...
- JS刷算法题:二叉树
Q1.翻转二叉树(easy) 如题所示 示例: 输入: 4 / \ 2 7 / \ / \ 1 3 6 9 输出: 4 / \ 7 2 / \ / \ 9 6 3 1 来源:力扣(LeetCode) ...
- Java刷题常用API
目录 输入输出 快速查看 最大最小值 string stringbuilder 集合 map queue stack set 优先队列 PriorityQueue (Heap) 数组 静态数组 动态数 ...
随机推荐
- 性能调优命令之jstack
jstack是java虚拟机自带的一种线程堆栈跟踪工具. /opt/java8/bin/jstack Usage: jstack [-l] <pid> (to connect to run ...
- nginx 的访问日志切割
1. 高级用法–使用 nginx 本身来实现 当 nginx 在容器里,把 nginx 日志挂载出来的时候,我们发现就不适合再使用 kill -USR1 的方式去分割日志这时候当然就需要从 nginx ...
- mybatis-plus 分页查询+ dao层抽象
1.配置文件添加paginationInterceptor @Configuration @MapperScan("fama.cost.*.mapper") public clas ...
- Auto ML自动调参
Auto ML自动调参 本文介绍Auto ML自动调参的算法介绍及操作流程. 操作步骤 登录PAI控制台. 单击左侧导航栏的实验并选择某个实验. 本文以雾霾天气预测实验为例. 在实验画布区,单击左上角 ...
- Django框架之路由层汇总
一 Django中路由的作用 URL配置(URLconf)就像Django 所支撑网站的目录.它的本质是URL与要为该URL调用的视图函数之间的映射表:你就是以这种方式告诉Django,对于客户端发来 ...
- Ckeditor 缺少图像源文件地址的解决 笨笨的人都看啦!
Ckeditor 本文是关于CKEditor 无法上传图片问题的一个解决.我大致写了一下遇到问题的过程,问题的出处,怎么解决的,原因是什么. 希望能够帮到有需要的大家,有些时候找不到问题的答案,真的是 ...
- 01:osi七层---基于TCP协议的套接字(socket)
1 : osi 七层,tcp/ip 五层 1 cs架构和bs架构2 互联网3 osi七层 tcp/ip五层 -物理层 -网线.光纤 -数据链路层 -网卡 - ...
- 使用Spring Data JPA 访问 Mysql 数据库-配置项
jpa操作数据库 注意:数据库采用的是本机数据库,下面是建表语句及初始化数据: SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- ---------- ...
- 基于ABP落地领域驱动设计-05.实体创建和更新最佳实践
目录 系列文章 数据传输对象 输入DTO最佳实践 不要在输入DTO中定义不使用的属性 不要重用输入DTO 输入DTO中验证逻辑 输出DTO最佳实践 对象映射 学习帮助 系列文章 基于ABP落地领域驱动 ...
- webapi发布在iis之后报错Http 403.14 error
服务器是 Windows Server 2008 R2 Enterprise 网上找了很多说是修改webconfig.试过之后没有效果,另外报错了. 最后才找到是因为webapi发布时选择的应用程序的 ...