目录
1 数组
int m = 5, n = 10;
// 初始化一个大小为 10 的 int 数组
// 其中的值默认初始化为 0
int[] nums = new int[n]
// 初始化一个 m * n 的二维布尔数组
// 其中的元素默认初始化为 false
boolean[][] visited = new boolean[m][n];
2 字符串
2.1 获取字符串的某个字符
String s1 = "hello world";
// 获取 s1[2] 那个字符 l
char c = s1.charAt(2);
2.2 字符串与char数组的互相转化
// 字符串转为char数组
char[] chars = s1.toCharArray();
chars[1] = 'a';
//char数组转为字符串
String s2 = new String(chars);
// 输出:hallo world
System.out.println(s2);
2.3 判断字符串是否相同
// 注意,一定要用 equals 方法判断字符串是否相同
if (s1.equals(s2)) {
// s1 和 s2 相同
} else {
// s1 和 s2 不相同
}
2.4 字符串的拼接
// 字符串可以用加号进行拼接
String s3 = s1 + "!";
// 输出:hello world!
System.out.println(s3);
2.5 获取某段字符串
//获取s中[l+1,r)的字符字串
s.substring(l + 1, r)
2.6 去除字符串的某个字符
//去除字符串中的空格
s = s.replaceAll("\\s+", " ");
2.7 去除字符串开头和结尾的空格
s = s.trim();
2.8 将字符串按" "进行划分,最终形成字符串数组
//数组内容为 {i,am,lihao}
String s = "i am lihao";
String[] words = s.split("\\s+");
3.动态数组ArrayList
3.1 ArrayList常用方法
// 判断数组是否为空
boolean isEmpty()
// 返回数组的元素个数
int size()
// 返回索引 index 的元素
E get(int index)
// 在数组尾部添加元素 e
boolean add(E e)
4.哈希表
4.1 哈希表的基本操作
// 判断哈希表中是否存在键 key
boolean containsKey(Object key)
// 获得键 key 对应的值,若 key 不存在,则返回 null
V get(Object key)
// 将 key, value 键值对存入哈希表
V put(K key, V value)
// 如果 key 存在,删除 key 并返回对应的值
V remove(Object key)
4.2 字母异位词分组
给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。
字母异位词 是由重新排列源单词的所有字母得到的一个新单词。
示例 1:
输入: strs = [“eat”, “tea”, “tan”, “ate”, “nat”, “bat”]
输出: [[“bat”],[“nat”,“tan”],[“ate”,“eat”,“tea”]]
示例 2:
输入: strs = [“”]
输出: [[“”]]
示例 3:
输入: strs = [“a”]
输出: [[“a”]]
思路以及代码:
你如何迅速判断两个字符串是异位词,主要考察数据编码和哈希表的使用:
你是否可以找到一种编码方法,使得字母异位词的编码都相同?找到这种编码方式之后,就可以用一个哈希表存储编码相同的所有异位词,得到最终的答案。
我们可以利用ASCLL表,将字符转化为数字,之后建立一个26位存储0/1的数组,字符串存在这个字符就在相应位置设置为1,这样即可完成编码
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
Map<String,List<String>> map = new HashMap();
for(String s:strs){
String code = encode(s);
//将编码相同的字符放在一起
map.putIfAbsent(code,new ArrayList());
map.get(code).add(s);
}
List<List<String>> res = new ArrayList();
for(List<String> i:map.values()){
res.add(i);
}
return res;
}
//将每个字符串输出为一个26位的0/1编码,1表示这个字符串有这个字符
public String encode(String s){
char[] count = new char[26];
for(char c:s.toCharArray()){
int i = c - 'a';
count[i]++;
}
return new String(count);
}
}
4.3 最长连续序列
给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。
请你设计并实现时间复杂度为 O(n) 的算法解决此问题。
示例 1:
输入:nums = [100,4,200,1,3,2]
输出:4
解释:最长数字连续序列是 [1, 2, 3, 4]。它的长度为 4。
示例 2:
输入:nums = [0,3,7,2,5,8,4,6,0,1]
输出:9
思路以及代码:
想找连续序列,首先要找到这个连续序列的开头元素,然后递增,看看之后有多少个元素还在 nums 中,即可得到最长连续序列的长度了。
那么我们可以先把他存在一个set里,之后找到set中不具有i-1元素的哪个i,其中这个i就可能是连续数字的起始元素,之后进行确认即可
class Solution {
public int longestConsecutive(int[] nums) {
Set<Integer> set = new HashSet();
int res = 0;
for(int i:nums){
set.add(i);
}
for(int i:set){
//说明i不是第一个
if(set.contains(i-1)){
continue;
}
int start = i;
int numlen = 1;
while(set.contains(start+1)){
start+=1;
numlen+=1;
}
res = Math.max(res,numlen);
}
return res;
}
}
5.栈和队列
5.1栈和队列的基本操作
// 队列的基本 API
class MyQueue<E> {
// 向队尾插入元素,时间复杂度 O(1)
void push(E e);
// 从队头删除元素,时间复杂度 O(1)
E pop();
// 查看队头元素,时间复杂度 O(1)
E peek();
// 返回队列中的元素个数,时间复杂度 O(1)
int size();
}
// 栈的基本 API
class MyStack<E> {
// 向栈顶插入元素,时间复杂度 O(1)
void push(E e);
// 从栈顶删除元素,时间复杂度 O(1)
E pop();
// 查看栈顶元素,时间复杂度 O(1)
E peek();
// 返回栈中的元素个数,时间复杂度 O(1)
int size();
}
6.常用数据结构
6.1 二叉堆
其中最长使用的是优先队列,也就是自动排序,以保证每次取出的要么是最大的要么是最小的,具体使用步骤如下:(默认是最小堆)
//初始化
PriorityQueue<ListNode> priorityQueue=new PriorityQueue<>((n1,n2)-> (n2-n1));
//添加元素
priorityQueue.offer(node);
//弹出元素
ListNode node=priorityQueue.poll();
//判空
priorityQueue.isEmpty()
//检索二叉堆头部 为空则返回null
priorityQueue.peek();
6.1.1 数组中的第K个最大元素
给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。
请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。
示例 1:
输入: [3,2,1,5,6,4], k = 2
输出: 5
示例 2:
输入: [3,2,3,1,2,4,5,5,6], k = 4
输出: 4
思路以及代码:
可以把小顶堆 pq 理解成一个筛子,较大的元素会沉淀下去,较小的元素会浮上来;当堆大小超过 k 的时候,我们就删掉堆顶的元素,因为这些元素比较小,而我们想要的是前 k 个最大元素嘛。
当 nums 中的所有元素都过了一遍之后,筛子里面留下的就是最大的 k 个元素,而堆顶元素是堆中最小的元素,也就是「第 k 个最大的元素」。
class Solution {
public int findKthLargest(int[] nums, int k) {
PriorityQueue<Integer> pq = new PriorityQueue();
for(int i:nums){
pq.offer(i);
//堆中元素大于k,就删除堆顶(其实就是把小的都删除了)
if(pq.size()>k){
pq.poll();
}
}
//此时,小根堆里面剩的是前k个大的元素
//堆顶元素最小,也就是数组中第k大的元素了
return pq.peek();
}
}