vlambda博客
学习文章列表

java刷算法题常用方法整理

数据类型、接口和类

  • 接口:抽象方法的集合,但没有特定方法的实现

  • 类:通过继承接口从而继承接口的抽象方法并针对不同的方法有自己的实现

接口 特点 常用类
List 元素不唯一 LinkedList、ArrayList
Set 元素唯一 HashSet、TreeSet
Map 键值映射 HashMap、TreeMap



常用类列表

该部分仅列出了在算法题中经常用到的类型与数据结构。

适用情况
数组 Array 既定长度,可模拟pair、tuple等immutable容器
动态数组 ArrayList 长度动态可改的灵活数组
栈 Stack LIFO后进先出
队列 Queue FIFO先进先出
集合 HashSet 当需要存储非重复元素或去重时,优先考虑该类型,但其不保证有序
哈希表 HashMap 实现O(1)的读取与写入键值对,但其不保证有序
优先队列 PriorityQueue 利用Heap进行排序性存值
数字 & 数学 - Number & Math
用途 语法 备注
最大整数 Integer.MAX_VALUE

最小整

Integer.MIN_VALUE
Collection接口Collection的定义如下:public interface Collection<E> extends Iterable<E> {}基础API接口:
abstract boolean add(E object)abstract boolean addAll(Collection<? extends E> collection)abstract void clear()abstract boolean contains(Object object)abstract boolean isEmpty()abstract boolean remove(Object object)abstract boolean removeAll(Collection<?> collection)abstract int size()abstract <T> T[] toArray(T[] array)abstract Object[] toArray()

静态数组 array

属性  length

.length 记得是属性而不是方法 arr.length 没有()

工具类Arrays

        List<T>   asList(T ...a)

             返回由指定数组支持的固定大小的列表返回由指定数组支持的固定大小的列表

                      sort(T[] a)

               将指定的数组按升序排序

                     String  toString(T[] a)

                    返回指定数组内容的字符串表示形式

动态数组 List & ArrayList

初始化

常规 - ArrayList更常用

     List<Integer> array = new ArrayList<>();    // 数组

     List<Integer> list = new LinkedList<>(); // 链表

ArrayList 构造器

   ArrayList()

          构造一个初始容量为10的空列表。
  ArrayList(int initialCapacity)
           构造一个具有指定初始容量的空列表。
  ArrayList(Collection<? extends E> c)
           构造一个列表,该列表包含指定集合的元素,其顺序由集合的迭代器返回
常用方法
oid add(int index, E element)

将指定的元素插入此列表中的指定位置。

boolean add(E e)

将指定的元素追加到此列表的末尾。

boolean contains(Object o)

返回true此列表是否包含指定的元素。

E get(int index)

返回此列表中指定位置的元素

boolean isEmpty()

Returns true if this list contains no elements.

E remove(int index)

删除此列表中指定位置的元素。

boolean remove(Object o)

如果存在指定元素,则从该列表中删除该元素的第一次出现。

Object[] toArray()

以正确的顺序(从第一个元素到最后一个元素)返回一个包含此列表中所有元素的数组。

<T> T[] toArray(T[] a)

返回一个数组,该数组按适当顺序(从第一个元素到最后一个元素)包含此列表中的所有元素;返回数组的运行时类型是指定数组的运行时类型。

int size()

返回此列表中的元素数。

void sort(Comparator<? super E> c)

根据指定的诱导顺序对列表进行排序 Comparator

链表 LinkedList

同样实现List接口的LinkedList与ArrayList不同,ArrayList是一个动态数组,而LinkedList是一个双向链表。所以它除了有LinkedList适合频繁地对列表进行增加或删除元素操作,因此LinkedList类可用于实现堆栈和队列

public void addFirst(Object o) //在链表头增添元素public void addLast(Object o) //在链表尾增添元素
public E getFirst() //获取链表首元素public E getLast() //获取链表尾元素
public Object removeFirst() //删除链表头元素,并返回该元素public Object removeLast() //删除链表尾元素,并返回该元素


 Vector(Stack)

Stack 是Vector的子类, java中Stack只有一个无参构造函数。

属于Stack的方法

push( num) //入栈pop() //栈顶元素出栈 返回empty() //判定栈是否为空 注意这里和Collection的区别peek() //获取栈顶元素search(num) //栈顶到该元素首次出现的位置的距离

 Queue:

Queue 和List 属于同一级,都继承了Collection

//add()和remove(),element()方法在失败的时候会抛出异常(不推荐) Queue<String> queue = new LinkedList<String>();
offer(object)poll() // 出队并返回peek() isEmpty()//队列为空返回true,否则返回falsesize()// 返回队列长度


 Deque 用LinkedList 代替使用
PriorityQueue

是Queue接口的实现,可以对其中元素进行排序,
可以放基本数据类型的包装类(如:Integer,Long等)或自定义的类
对于基本数据类型的包装器类,优先队列中元素默认排列顺序是升序排列
但对于自己定义的类来说,需要自己定义比较器
常用方法 和上面Queue一样

小根堆

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的大根堆。在当中增加元素会扩容,只是开始指定大小

PriorityQueue方法(Queue接口方法)

方法:offer, poll, peek, isEmpty, size

offer

 
   
   
 
.offer(E e); // 在堆中加入元素e,并调整堆。若成功入堆返回值true,否则返回false --- O(logN)

poll

 
   
   
 
.poll(); // 弹出堆顶元素,并重新调整堆,返回出队元素e --- O(logN)

peek

 
   
   
 
.peek(); // 查看堆顶元素, 返回值堆顶元素e --- O(1)

isEmpty

 
   
   
 
.isEmpty() // 若队空返回true, 否则返回false --- O(1)

size

 
   
   
 
.size() // 返回队中元素个数 --- O(1)

集合 Set - HashSet

性质:Set中没有重复元素,重复添加的元素抛弃

初始化

默认构造函数

Set<Integer> set = new HashSet<>();

把集合如Stack、Queue、List等Collection作为参数

// List<Integer> list = new ArrayList<>....;
// Set<Integer> set = new HashSet<>(list);

HashSet方法(Set接口方法)

方法:add, remove, contains, isEmpty, size

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 (TreeSet)

.first() // 返回集合里的最小值(若给了比较器从大到小则是返回最大值)

last (TreeSet)

.last() // 返回集合里的最大值(若给了比较器从大到小则是返回最小值)



散列表 HashMap

性质:使用健值对的方式存储数据 <Key,Value>

初始化

<Key, Value> key和value是任何Collection或任何Object

 
   
   
 
Map<Characters, Integer> map = new HashMap<>();

HashMap方法 (Map接口方法)

方法:put, get, getOrDefault, containsKey, containsValue, keySet, values, isEmpty, size

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)

containsValue

 
   
   
 
.containsValue(V value); // 在Map中若存在value,则返回true,否则返回false --- O(1)

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)

字符串

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);

类方法

String.valueOf( 一个参数Object/基本数据类型 ) 返回传入参数obj的toString(),若为空返回字符串"null"。若为基本类型调用其 包装类的toString方法( Integer.toString(i)

String 方法

方法: charAt, length, substring, equals, indexOf, lastIndexOf, replace, toCharArray, trim, split, toLowerCase, toUpperCase
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 是(暴力查找字符串,不是KMP)
 
   
   
 
.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 只能换char
 
   
   
 
.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
StringBuilder

初始化

 
   
   
 
StringBuilder sb = new StringBuilder();

instance方法

方法: append, charAt, length, setCharAt, insert,  delete, reverse, toString
charaAt
 
   
   
 
.charAt(int index); // 返回index位置的char --- O(1)

length
 
   
   
 
.length(); // 返回缓冲字符串长度 --- O(1)

setCharAt
 
   
   
 
.setCharAt(int index, char ch); // 设置index位置的char为ch --- O(1)

insert
 
   
   
 
.insert(int offset, String str); // 在offer位置的插入字符串str--- O(m + n)

deleteCharAt
 
   
   
 
.deleteCharAt(int index); // 删除index位置的char --- O(n)

.deleteCharAt(sb.length() - 1); // 删除最后一个char --- O(1)

delete
 
   
   
 
.delete(int start, int end); // 删除[start, end)位置的char --- O(n)

reverse
 
   
   
 
.reverse(); // 反转缓存字符串 --- O(n)

toString
 
   
   
 
.toString(); // 返回一个与构建起或缓冲器内容相同的字符串 --- O(n)