语言基础
编程基础
算法中常见的方法
1.求两个整数的最大公约数
public static int gcd(int x,int y){
if(y==0)
return x;
return gcd(y,x%y);
}
2.求两个整数的最小公倍数
public static int lcm(int x,int y){
return x*y/gcd(x,y);
}
3.判断一个整数是否为质数
public static boolean isPrime(int x){
if(x==1)
return false;
for(int i=2;i<x++){
if(x%i==0)
return false;
}
return true;
}
数学方法
1.导包import java.util.*
2.Math.xxx(参数)使用函数
取最大最小值max/min(int/long/float/double a,int/long/float/double b)
sqrt(double a)取a的平方根
cbrt(double a)取b的立方根
pow(double a,double b)取a的b次方根
abs(int/long/float/double)取绝对值
大小写转换
.toLowerCase()字符串中的字母全部转换为小写,其他不变
.toUpperCase()字符串中的字母全部转换为大写,其他不变
异或转化(将大写转换为小写,小写转换为大写)
Scanner scan=new Scanner(System.in);
String str=scan.next();
for(int i=0;i<str.length();i++){
char x=str.charAt(i);
if(x>='a' && x<='z')
x^=32;
else if(x>='A' && x<='Z')
x^=32;}
集合框架
数组
import java.util.Arrays包
Arrays.sort(数组名arr)//进行升序排序
Arrays.fill(数组名arr,数值)//将数组全部填充为某个数值
int[] arr={1,2,3,5,6};//静态初始化数组
int[] arr=new int[5];//动态初始化数组
//数组的遍历
for(int i=0;i<arr.length;i++){
System.out.println(arr[i]);}
for(int x:arr){
System.out.println(x);}
List集合
1.导入Java.util包(import java.util.*)
2.创建ArrayList对象
List<Integer>list=new ArrayList<>();
add(Object element)向列表的尾部添加指定元素
size()返回列表中的元素个数
get(int index)返回列表中指定位置的元素
isEmpty()判断列表是否为空
contains(Object o)判断列表是否包含元素o
remove(int index)移除列表中指定位置的元素,并返回被删元素
排序
数组排序
升序Arrays.sort();
降序Arrays.sort(T[] arr,Comparator<T> c)利用Comparator接口
Arrays.sort(arr,new Comparator<Integer>(){
public int compare(Integer a,Integer b){
return b-a;
}
System.out.print(Arrays.toString(arr));
});//b-a是降序,a-b是升序
利用lambda排序
Arrays.sort(arr,(o1,o2)->o1-o2);//o1-o2为升序,o2-o1为降序
for(int i=0;i<arr.length;i++){
System.out.print(arr[i]+" ");
}
集合排序
可以出现重复的元素
List<Integer> list=new ArrayList<>();
list.add(1);
list.add(2);
list.add(4);
list.add(6);
Collections.sort(list);//升序排序
Collections.sort(list,(o1,o2)->o2-o1);//降序排序
for(int i=0;i<list.size();i++){
System.out.print(list.get(i)+" ");
}
}
set集合
不允许出现重复元素
特点:1.可以用来去重;2.元素无序
导包import java.util.*
HashSet类
创建HashSet对象set,用于保存字符串元素
Set<String> set=new HashSet<>();
常用方法
add(Object obj)在set集合中添加元素
size()返回set集合中元素的个数
remove(object o)删除set集合中的元素
contains()判断set中是否包含某元素
clear()移除此set中的所有元素
MAP集合
1.导入Java.util.Map.*包
2.通过hashmap实现类创建对象
Map<Integer,Integer>map=new HashMap<>();
HashMap是无序的(即不会记录插入的顺序),最多允许一条记录的键为null,不支持线程同步
put(K key,V value)将键值映射存放到Map集合中
get(Object key)返回指定键所映射的值
size()返回Map集合中数据的数量
entrySet():将Map集合每个key-value转换为一个Entry对象并返回由所有的Entry对象组成的Set集合
Set<Map.Entry<String, String>> entryseSet=map.entrySet();
for (Map.Entry<String, String> entry:entryseSet) {
System.out.println(entry.getKey()+","+entry.getValue());
}
getOrDefault(K key,Object value)获取指定key对应对value,如果找不到key,则返回设置的默认值
stack集合
1.导包 import java.util.*;
2.初始化
Stack<Integer>stack=new Stack<>();
3.stack的操作
stack.push(1);//将元素压入栈中
stack.push(2);
int a=stack.pop();//将元素从栈中弹出
System.out.println(stack.peek());//查看堆顶的元素,但是不用从栈顶弹出
stack.isEmpty;//判断堆栈是否为空
Queue
1.导包import java.util.*
2.通过LinkedList创建对象
Queue<Integer>queue=new LinkedList<>();
3.常用方法
Boolean add(Object element)从队尾压入元素,返回是否成功
Object poll()删除并返回队头被删除的那个元素
Object peek()返回队头元素,但不删除
boolean isEmpty()判断是否为空
例题
例题1.将n个正整数排成一排,相邻数字首位相接,组成最大的整数。
解题思路:应该要将两个数相连所得相同长度的字符串相比才可以判断顺序,如10,1组合时,110>101,将数字当作字符串输入
import java.util.*;
Scanner scan=new Scanner(System.in);
int n=scan.nextInt();
String[] str=new String[n];
for(int i=0;i<n;i++){
str[i]=scan.next();
}
Arrays.sort(str,(o1,o2)->(o2+o1).compareTo(o1+o2));
StringBuilder str1=new StringBuilder();
for(x:str){
str1.append(x);
}
System.out.println(str1);
例2.输入两个数n和m,对1到n之间的数进行排序,排序规则为:若两数的各位数字之和相等,则数值小的排在前面;若两数的各位数字之和不相等,则数位和较小的排在前面
思路:利用二维数组对数字进行存储,每行的第一个数字存储该数值,第二个数字存储该数字的各位数字之和
Scanner scan=new Scanner(System.in);
int n=scan.nextInt();
int m=scan.nextInt();
int[][] arr=new int[][2];
for(int i=0;i<n;i++){
arr[i][0]=i+1;
String x=arr[i][0]+" ";//通过加" "可以把数字转换为字符串
for(int j=0;j<x.length();j++){
arr[i][1]=x.charAt(j)-'0';//通过减去‘0’字符,将字符串转换为数字
}
}
Arrays.sort(arr,(o1,o2)->o1[1]==o2[1]?01[0]-o2[0]:o[1]-o2[1]);
System.out.print(arr[m-1][0]);
补充:Arrays.sort()自定义排序
Java中Arrays.sort自定义一维数组、二维数组的排序(以及出现的问题)_arrays.sort(people, (a, b) ->-CSDN博客
基础算法
排序
冒泡排序
对相邻元素进行选择(O(n2))
public static void main(String[] arg){
Scanner scan=new Scanner(System.in);
int n=scan.nextInt();
int []arr=new int[n];
for(int i=0;i<arr.length;i++){
for(int j=i+1;j<arr.length;j++){
if(arr[i]>arr[j]){
int temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
}
}
选择排序
对整体进行选择(O(n2))
for(int i=0;i<arr.length;i++){
int min=i;
for(int j=i+1;j<arr.length;j++){
if(arr[j]<arr[min])
min=j;
}//找到一堆里最小的一个元素
if(i!=min){//若i不是最小元素,则将i交换到最小元素的位置
int temp=arr[i];
arr[i]=arr[min];
arr[min]=temp;
}
}
插入排序
对于未排序的序列,在已排序的序列中从后向前扫描,找到相应的位置并插入
for(int i=1;i<arr.length;i++){
int key=arr[i];
int j=i-1;
while(j>=0&&arr[j]>key){
arr[j+1]=arr[j];
j--;}
arr[j+1]=key;
}
快速排序
递归的思想,最坏运行时间(O(n2)),平均排序时间(O(nlogn))
归并排序
数据结构
基础数据结构
链表
单链表
(只能处理后面的操作,不能找到前一个点)
int e[N],int data[N],idx表示当前已用的内存空间,用于开点,用-1表示空
e[i]:地址为i的结点的下一个结点的数组下标
data[i]:地址为i的结点上的数据
插入一个节点到尾部:e[tail]=++idx,e[idx]=-1,data[idx]=val,tail=idx;
往地址adr后插入一个结点:e[++idx]=e[adr],e[adr]=idx,data[idx]=val;
将adr后面的结点删除(adr不为tail):e[adr]=e[e[adr]];
双链表
增加一个prev数组作为指向前一个元素的指针
例题
输入n和m,表示对初始状态为1到n的数从小到大排序,后续有m次操作
从第二行到第m+1行,每行三个数字x,y,z,若z=0,则将x移动到y之后,若z=1,则将x移动到y之前
public static void del(int x){//删除元素
int a=pre[x],b=next[x];
next[a]=b;
pre[b]=a;}
public static void add(int x,int y){//把x插入y后面
int z=next[y];
pre[z]=x;
pre[x]=y;
next[y]=x;
next[x]=z;
}
//
public static void main(String[] args){
Scanner scan=new Scanner(System.in);
int n=scan.nextInt();
int m=scan.nextInt();
for(int i=1;i<n;i++){
pre[i]=i-1;
next[i]=i+1;}
next[0]=1;
pre[0]=n;
next[n]=0;
pre[n]=n-1;
for(int i=0;i<m;i++){
int x=scan.nextInt();
int y=scan.nextInt();
int z=scan.nextInt();
if(z==1)y=pre[y];//插入前面相当于插入前面的后面
del(x);
add(x,y);
}
for(int i=next[0];i>0;i=next[i]){
System.out.print(i+" ");}
栈
用数组表示栈:int stk[N],top;
往栈内新增元素:stk[++top]=x;
删除栈顶元素:top--;
判断栈是否为空:top==0;
队列
优先队列PriorityQueue
Java之PriorityQueue的用法_java priorityqueue用法-CSDN博客
导包:
import java.util.*;
初始化:
Queue<Integer> priorityQueue2 = new PriorityQueue<>(10);
底层数组默认容量是11,默认为小根堆,如果需要构造大根堆需要重写比较器
PriorityQueue<Integer> priorityQueue = new PriorityQueue<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2.compareTo(o1);
}
});
//法2
PriorityQueue<Integer>queue=new PriorityQueue<>((o1,o2)->o2-o1);
基本操作方法:
Queue<Integer> priorityQueue = new PriorityQueue<>();
int[] array = {1,3,2,6,5,7,8,9,10,0};
for(int x : array) {
// 1, 插入数据
priorityQueue.offer(x);
}
// 2,获取优先级最高的数据
int ret1 = priorityQueue.peek();
System.out.println("获取优先级最高的数据:" + ret1);
// 3,删除优先级最高的数据
int ret2 = priorityQueue.poll();
System.out.println("删除优先级最高的数据:" + ret2);
// 4,获取优先级队列中数据个数
int size = priorityQueue.size();
System.out.println("数据个数:" + size);
// 5, 清空优先级队列
priorityQueue.clear();
// 6, 查看队列是否为空
boolean bl = priorityQueue.isEmpty();
System.out.println("队列是否为空:" + bl);
}
ST表(稀疏表)
RMQ问题(区间最值查询)
指对于一个数组,每次给出一个区间[1,r],要求返回区间内的最大值或最小值(利用倍增和动态规划思想)