sort:
1:java.util.Arrays中的静态方法Arrays.sort()方法,针对基本数据类型和引用对象类型的数组元素排序,对于字符串可以先转换为char[]数组后进行排序
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
return new ArrayList<>(Arrays.stream(strs)
.collect(Collectors.groupingBy(
str -> {
char[] s = str.toCharArray();
Arrays.sort(s);
return new String(s);
}
))
.values());
}
}
2:java.util.Collections中的静态方法的Collections.sort()方法,针对集合框架中的动态数组,链表,树,哈希表等( ArrayList、LinkedList、HashSet、LinkedHashSet、HashMap、LinkedHashMap )进行排序。下面分别介绍两种用法。
Collections.sort(list,new Comparator<Integer>(){//升序排序
public int compare(Integer str1,Integer str2){
String s1=str1+""+str2;
String s2=str2+""+str1;
return s1.compareTo(s2);//变成-s1.compareTo(s2)就是降序排序了
}
});
reverse:
对于集合,使用Collections.reverse()
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
Collections.reverse(list);
对于字符串,使用StringBuilder.reverse()
String str = "Hello, World!";
StringBuilder reversedStr = new StringBuilder(str).reverse();
ArrayList:
对应于C++的vector容器
#等价于vector<int>vec[maxn]
final static List<Integer>[]list=new ArrayList[MAXN];
static{
for (int i = 0; i < list.length; i++) {
list[i]=new ArrayList<>();
}
}
将元素插入到指定位置的 arraylist 中
public boolean add(E e)
从集合中获取元素,参数是索引编号,返回值就是对应位置的元素
public E get(int index)
从集合中删除元素,参数是索引编号,返回值就是被删除的元素
public E remove(int index)
获取集合的尺寸长度,返回值是集合中包含的元素个数
public int size()
Stack和Queue容器:
Stack:
import java.util.Stack;
public class StackExample {
public static void main(String[] args) {
Stack<Integer> stack = new Stack<>();
// 添加元素
stack.push(1);
// 查看栈顶元素
int top = stack.peek();
// 移除栈顶元素
int popped = stack.pop();
}
}
Stack
的基本操作:
push(E item)
:将元素压入栈顶。pop()
:移除并返回栈顶元素。peek()
:返回栈顶元素,但不移除。isEmpty()
:检查栈是否为空。
Queue:Queue在Java中是一个接口,它的实现类有PriorityQueue和LinkedList,LinkedList即为C++种的Queue
import java.util.LinkedList;
import java.util.Queue;
public class QueueExample {
public static void main(String[] args) {
Queue<Integer> queue = new LinkedList<>();
// 添加元素
queue.add(1);
// 查看队首元素
int front = queue.peek();
// 移除队首元素
int removed = queue.poll();
// 检查队列是否为空
boolean isEmpty = queue.isEmpty();
}
}
Queue
的基本操作:
add(E e)
:将元素添加到队列尾部。poll()
:移除并返回队首元素,如果队列为空则返回null
。peek()
:返回队首元素,但不移除,如果队列为空则返回null
。isEmpty()
:检查队列是否为空。
TreeSet容器:
TreeSet即对应C++中的set:
Integer[]nums={1,2,3,4,5};
ArrayList<Integer>list=new ArrayList<>(List.of(nums));
Collections.addAll(list,4,5,6);
TreeSet<Integer> s = new TreeSet<>(list);
// 遍历集合中的所有元素
Iterator<Integer> it = s.iterator();
while (it.hasNext()) {
Integer element = it.next();
if (it.hasNext()) {
System.out.print(element + " ");
} else {
System.out.print(element);
}
}
contains(Object o)
:检查集合中是否包含指定元素。first()
和last()
:获取集合中的第一个和最后一个元素。ceiling(E e)
和floor(E e)
:分别返回大于或等于给定元素的最小元素和小于或等于给定元素的最大元素。higher(E e)
和lower(E e)
:分别返回严格大于和严格小于给定元素的最小和最大元素。
boolean remove(Object o)
:从集合中删除指定的元素o
,如果删除成功则返回true
。
Multiset容器:
Java中没有直接与C++的Multiset对应的容器,不过可以用TreeMap模拟实现,以leetcode该题为例 480. 滑动窗口中位数
class Solution {
public double[] medianSlidingWindow(int[] nums, int k) {
int n = nums.length;
double[] ans = new double[n-k+1];
Set<int[]> set = new TreeSet<>((a, b)->a[0]==b[0] ? Integer.compare(a[1], b[1]) : Integer.compare(a[0], b[0]));
for(int i=0; i<k; i++) set.add(new int[]{nums[i], i});
for(int i=k, j=0; i<n; i++, j++){
ans[j] = findMid(set);
set.add(new int[]{nums[i], i});
set.remove(new int[]{nums[i-k], i-k});
}
ans[n-k] = findMid(set);
return ans;
}
double findMid(Set<int[]> set){
int mid = (set.size() - 1) / 2;
var it = set.iterator();
while(mid-->0) it.next();
return set.size()%2 == 0 ? ((double)it.next()[0] + it.next()[0]) / 2 : it.next()[0];
}
}
TreeMap:
等价于C++的map
HashMap:
等价于c++的unordered_map
pair和tuple:
如果其中的元素类型相同则可以直接用java的数组来替代:
final int maxn = 200000 + 5;
List<int[]> vec1 = new ArrayList<>(maxn);
vec1.add(new int[]{1, 2});
vec1.add(new int[]{3, 4});
List<int[]> vec2 = new ArrayList<>(maxn);
vec2.add(new int[]{1, 2, 3});
vec2.add(new int[]{4, 5, 6});
如果其中的元素类型不同,对于Pair可以使用AbstractMap.SimpleEntry替代
Queue<AbstractMap.SimpleEntry<TreeNode, Integer>> queue=new LinkedList<>();
queue.add(new AbstractMap.SimpleEntry<>(root,1));
lower_bound/upper_bound:
方法1:转化为TreeSet容器之后使用TreeSet的ceiling和higher函数,对于Java容器可以直接在new的时候传入Collection<? extends E>来初始化,所以Set,List,Map皆可以互相转换
Integer[]nums={1,2,3,4,5};
ArrayList<Integer>list=new ArrayList<>(List.of(nums));
Collections.addAll(list,4,5,6);
//对于Java容器可以直接在new的时候传入Collection来初始化
TreeSet<Integer> s = new TreeSet<>(list);
// 查找元素是否存在
boolean contains30 = s.contains(30);
System.out.println("Contains 30: " + contains30);
// 返回大于或等于30的第一个元素,没有找到返回null
Integer foundElement = s.ceiling(30);
// 返回大于30的的第一个元素,没有找到返回null
Integer foundHigherElement=s.higher(30); //返回大于30的第一个元素
System.out.println("Ceiling of 30: " + foundHigherElement);
方法2:手写lower_bound和upper_bound函数,针对于数组而言实现
//返回从l~r区间,大于等于value的第一个数的下标,没有则返回-1
public int lower_bound(int[] nums, int l, int r, int value) {
while(l<=r){
int mid=(l+r)/2;
//nums[mid]<value,不符合条件继续往右
if(nums[mid]<value){
l=mid+1;
}
else{
//nums[mid]>=value,尝试继续往左
if(mid==0||nums[mid-1]<value){
return mid;
}
else{
r=mid-1;
}
}
}
return -1; //代表没有该位置
}
//返回从l~r区间,大于value的第一个数的下标,没有则返回-1
public int upper_bound(int[] nums, int l, int r, int value) {
while(l<=r){
int mid=(l+r)/2;
//nums[mid]<=value,不符合条件继续往右
if(nums[mid]<=value){
l=mid+1;
}
else{
//nums[mid]>value,尝试继续往左
if(mid==0||nums[mid-1]<=value){
return mid;
}
else{
r=mid-1;
}
}
}
return -1; //代表没有该位置
}
priority_queue:
等价于C++的priority_queue
import java.util.PriorityQueue;
public class Main {
static PriorityQueue<Integer>q=new PriorityQueue<>(Integer::compareTo);
public static void main(String[] args) {
q.add(0);
q.add(1);
while(!q.isEmpty()){
Integer peek = q.peek();
q.poll();
System.out.println(peek);
}
}
}