Java 
2024年 Java 面试八股文(20w字)_java八股文2023-CSDN博客 
SQL 
SQL 50 题(MySQL 版,包括建库建表、插入数据等完整过程,适合复习 SQL 知识点)_sql50题-CSDN博客 
SQL常见语句及用法_sql语句大全及用法-CSDN博客 
SQL中的 聚合函数 ,where ,having_where后面可以跟聚合函数吗-CSDN博客 
Spring 
面试被问了几百遍的 IOC 和 AOP ,一篇文章带你搞清楚!!!_ioc和aop的原理面试-CSDN博客 
Sentinel 
sentinel (史上最全)-CSDN博客 
Gradle&Maven 
gradle中的build script详解_gradle buildscript-CSDN博客 
[Gradle和Maven的区别-CSDN博客](https://blog.csdn.net/weixin_45626288/article/details/131973787?ops_request_misc={"request_id"%3A"172024305816800185819613"%2C"scm"%3A"20140713.130102334.."}&request_id=172024305816800185819613&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-2-131973787-null-null.142^v100^pc_search_result_base8&utm_term=gradle  maven&spm=1018.2226.3001.4187)
线程池和锁 
面试+基础-----详细解读多线程(线程池、锁、死锁…)_多线程井发、死锁问题、线程池原理等-CSDN博客 
Java 多线程:彻底搞懂线程池_java线程池-CSDN博客 
Netty 
【硬核】肝了一月的Netty知识点-CSDN博客 
超详细Netty入门,看这篇就够了!_netty框架-CSDN博客 
JUnit 
JUnit详解-CSDN博客 
Pytest 
Python测试框架之pytest详解_pytest框架详解-CSDN博客 
Docker 
docker入门,这一篇就够了。-CSDN博客 
docker run [可选参数] image 命令 #启动容器(无镜像会先下载镜像) 
#参数说明 
–name = “Name”   容器名字 
-c   后面跟待完成的命令 
-d   以后台方式运行并且返回ID,启动守护进程式容器 
-i   使用交互方式运行容器,通常与t同时使用 
-t   为容器重新分配一个伪输入终端。也即启动交互式容器 
-p   指定容器端口    -p 容器端口:物理机端口  映射端口 
-P   随机指定端口 
-v   给容器挂载存储卷
 
JVM 
[JAVA内存分配原理解析–栈、堆、常量池_堆,栈,常量池详解-CSDN博客](https://blog.csdn.net/gb702250823/article/details/92801716?ops_request_misc={"request_id"%3A"171151029816800225558425"%2C"scm"%3A"20140713.130102334.."}&request_id=171151029816800225558425&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-2-92801716-null-null.142^v100^pc_search_result_base2&utm_term=java  常量池 栈 堆&spm=1018.2226.3001.4187)
java的垃圾回收(GC)详解_java gc-CSDN博客 
Java - 类加载器_java类加载器-CSDN博客 
常用数据结构和库 
java刷题前常用的数据结构及方法_java刷题常用方法-CSDN博客 
ACM模式 
1 2 3 4 5 6 7 8 import  java.util.Scanner;public  class  Main  {    public  static  void  main (String[] args)  {          } } 
 
输入输出 
1、输入整数、字符串数组 
第一行输入n, m
第二行输入n个整数
第三行输入m个字符串
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 import  java.util.Scanner;import  java.util.Arrays;public  class  MyScanner  {public  static  void  main (String[] args)  {	 	 	Scanner  sc  =  new  Scanner (System.in);		 	System.out.println("输入数据:" );	 	 	int  n  =  sc.nextInt(); 	int  m  =  sc.nextInt(); 	int [] arr = new  int [n];	 	String[] str = new  String [m]; 	 	 	for (int  i=0 ; i<n; i++) { 		arr[i] = sc.nextInt(); 	} 	 	for (int  i=0 ; i<m; i++) { 		str[i] = sc.next(); 	} 	      	TestSc(n, m, arr); 	TestStr(str); 	 	System.out.println("Test01 End" ); 	 	 	sc.close(); } public  static  void  TestSc (int  n, int  m, int [] arr)  {	System.out.println("数据n:"  + n + ", 数据m:"  + m); 	System.out.println(Arrays.toString(arr)); } public  static  void  TestStr (String[] str)  {	System.out.println(Arrays.toString(str)); } } 
 
若输入的字符串中想要包含空格,使用scanner.nextLine()换行后用scanner.nextLine()进行读入,见情形7.
2、输入二维数组 
第一行输入n, m
第二行开始输入二维数组。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 import  java.util.Arrays;import  java.util.Scanner;public  class  MyScanner2  {public  static  void  main (String[] args)  {	 	Scanner  sc  =  new  Scanner (System.in);		 	System.out.println("输入数据:" );	   	 	int  n  =  sc.nextInt(); 	int  m  =  sc.nextInt(); 	int [][] arr2 = new  int [n][m];	 	System.out.println("Test02 输入二维数组数据:" );   	 	for (int  i=0 ; i<n; i++) { 		for (int  j=0 ; j<m; j++) { 			arr2[i][j] = sc.nextInt(); 		} 	}   	TestSc(n, m, arr2); 	 	sc.close(); } public  static  void  TestSc (int  n, int  m, int [][] arr)  {	System.out.println("数据n:"  + n + ", 数据m:"  + m); 	for (int  i=0 ; i<n; i++) { 		System.out.println(Arrays.toString(arr[i])); 	} 	System.out.println("数组行数: arr.length= " + arr.length); 	System.out.println("数组列数: arr[0].length= " + arr[0 ].length); } } 
 
3、输入字符串 
输入字符串,用空格隔开。
next()和nextLine()区别。
import java.util.Scanner; 
/* 
*next()读取到空白停止,在读取输入后将光标放在同一行中。 
*nextLine()读取到回车停止 ,在读取输入后将光标放在下一行。 
*/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public  class  MyScanner3  {public  static  void  main (String[] args)  {	 	Scanner  sc  =  new  Scanner (System.in);		 	System.out.println("输入字符串:" );		 	 	 	String  str  =  sc.next();   	 	String  str2  =  sc.nextLine();   	System.out.println("str:"  + str); 	System.out.println("str2:"  + str2); 	 	 	sc.close(); } } 
 
4、输入字符串分割为数组 
先用scanner.nextLine()读入字符串,再将字符串分割为字符数组或字符串数组。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 import  java.util.*;public  class  MyScanner4  {public  static  void  main (String[] args)  {	 	Scanner  sc  =  new  Scanner (System.in);	 	System.out.println("输入字符串数组:" ); 	 	String str; 	str = sc.nextLine(); 	 	char [] ch = new  char [str.length()]; 	for (int  i=0 ; i<str.length(); i++) { 		 		ch[i] = str.charAt(i); 		System.out.println(ch[i] + " " ); 	} 	System.out.println("END" ); 	 	 	String[] strs = str.split(" " ); 	System.out.println(Arrays.toString(strs));   } } 
 
5、连续输入数字和字符串 
区别于情形1,对于不能采用for循环的方式获取String。采用情形5,6用来处理。
采用while(scanner.hasNext()) 循环,实现连续输入。
格式:数字,空格,字符串。
或: 数字,回车,字符串
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 import  java.util.Scanner;public  class  MyScanner5  {public  static  void  main (String[] args)  {	 	Scanner  sc  =  new  Scanner (System.in); 	 	while (sc.hasNext()) {					 		int  n  =  sc.nextInt(); 		String  str  =  sc.next(); 		Tes(n, str); 	} 		 	sc.close(); } public  static  void  Tes (int  n, String str)  {	System.out.println("n = "  + n); 	System.out.println("str = "  + str);	 	System.out.println("str.length = "  + str.length()); } } 
 
6、换行输入数字和字符串 
也采用scanner.nextLine(),将光标移到下一行。再继续读入字符串。
第一行输入整数n,m,第二行开始输入字符串。或
第一行输入整数n,第二行输入m,第三行开始输入字符串。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 import  java.util.*;public  class  MyScanner6  {public  static  void  main (String[] args)  {	Scanner  sc  =  new  Scanner (System.in); 	int  n  =  sc.nextInt(); 	int  m  =  sc.nextInt(); 	 	 	sc.nextLine(); 	 	String  s  =  sc.nextLine(); 	String  str  =  sc.nextLine(); 	 	System.out.println("n = "  + n + " , m = "  + m); 	System.out.println("s = "  + s); 	System.out.println("str = "  + str); 			 	sc.close(); } } 
 
7、换行输入数字和字符串(需要包含空格) 
采用scanner.nextLine(),将光标移到下一行。再继续读入字符串。
第一行输入n,
第二行开始输入n行字符串,字符串中包含空格。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 import  java.util.Scanner;public  class  MyScanner7  {public  static  void  main (String[] args)  {	 	Scanner  sc  =  new  Scanner (System.in); 	 	int  n  =  sc.nextInt(); 	String[] strs = new  String [n];  	 	sc.nextLine(); 	 	for (int  i=0 ; i<n; i++) { 		String  str  =  sc.nextLine(); 		strs[i] = str;			 	} 	 	Tes2(strs); 	System.out.println("End" );		 	sc.close(); } public  static  void  Tes2 (String[] strs)  {	for (int  i=0 ; i<strs.length; i++) { 		String  str  =  strs[i]; 		System.out.println(str); 	} } } 
 
int 转Integer 
1 2 3 int  num=1 ;Integer  i  =  Integer.valueOf(num);
 
Integer转int 
1 int  num  =  integer.intValue();
 
int到String数据类型的转换  
1 2 3 int  num;Integer.toString(num); 
 
或者String.valueOf(num); 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public  class  HelloWorld  {  public  static  void  main (String[] args)  {         int  num=100 ;     String a="" +num;     System.out.println(a);         Integer num2=100 ;     String b=Integer.toString(num2);     System.out.println(b);                    String c=String.valueOf(num2);     System.out.println(c); } } 
 
String到int类型的转换  
1 2 3 4 5 6 7 String  s  =  "100" int  d  =  Integer.parseInt(s);              int  e=Integer.parseInt(s);     System.out.println(e); 
 
ArrayList动态转换为Array数组 
1 String [] array=list.toArray(new  String [size]); 
 
除此之外,ArrayList 还有以下的常用的方法:
1 2 3 4 5 6 7 8 9 10 11 void  add (int  index, E element)  将指定元素插入此列表中的指定位置。boolean  add (E e) 将指定的元素追加到此列表的末尾。boolean  contains (Object o) 如果此列表包含指定的元素,则返回 true  。E get (int  index)  返回此列表中指定位置的元素。 int  indexOf (Object o)  返回此列表中第一次出现的指定元素的索引,如果此列表不包含该元素,则返回-1 。boolean  isEmpty ()  如果此列表不包含任何元素,则返回 true  。int  lastIndexOf (Object o) 返回此列表中指定元素最后一次出现的索引,如果此列表不包含该元素,则返回-1 。E remove (int  index)  删除此列表中指定位置的元素。 boolean  remove (Object o) 从该列表中删除指定元素的第一个匹配项(如果存在)E set (int  index, E element)  用指定的元素替换此列表中指定位置的元素。 int  size ()  返回此列表中的元素数。
 
Array数组转为ArrayList 
1 List<String>list= Arrays.asList(array) 
 
Arrays的常用方法 
1 2 3 4 5 6 7 8 9 10 11 12 13 int  nums[]=new  int [100 ];nums.length; Arrays.toString(nums) Arrays.sort(nums) Arrays.fill(nums) Arrays.equal(nums) Arrays.copyof(nums) Arrays.compare(nums) Arrays.binarySearch(nums) 
 
Arrays.sort()重写Comparator:
1 2 3 4 5 6 Arrays.sort(nums,new  Comparator <int  []>(){     public  int  compare (int []nums1, int []nums2) {         return  nums1[0 ]-nums2[0 ];     } }); 
 
ArrayList的常用用法 
Array:只可存储基本数据类型和对象。被设置为固定大小 。所包含的方法没有ArrayList多 
ArrayList:只能存储对象 。是一个可变数组 ,大小可自动调整。有很多操作方法:addAll 、removeAll、iteration等。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 ArrayList  list  =  new  ArrayList ();list.add("迪丽热巴" ); ArrayList<String> sites = new  ArrayList <String>();         sites.add("Google" );         sites.add("Runoob" );         sites.add("Taobao" );         sites.add("Weibo" );         sites.remove(3 );  sites.size(); Collections.sort(sites); sites.contains(); 这个方法括号中类型是list,拼接      void  add (int  index, E element)  将指定元素插入此列表中的指定位置。boolean  add (E e) 将指定的元素追加到此列表的末尾。boolean  contains (Object o) 如果此列表包含指定的元素,则返回 true  。E get (int  index)  返回此列表中指定位置的元素。 int  indexOf (Object o)  返回此列表中第一次出现的指定元素的索引,如果此列表不包含该元素,则返回-1 。boolean  isEmpty ()  如果此列表不包含任何元素,则返回 true  。int  lastIndexOf (Object o) 返回此列表中指定元素最后一次出现的索引,如果此列表不包含该元素,则返回-1 。E remove (int  index)  删除此列表中指定位置的元素。 boolean  remove (Object o) 从该列表中删除指定元素的第一个匹配项(如果存在)E set (int  index, E element)  用指定的元素替换此列表中指定位置的元素。 int  size ()  返回此列表中的元素数。
 
Collections类  
对list进行反转
1 2 3 4 Collections.reverse(list) Collections.sort(numbers);  Collections.binarySearch(numbers, 3 );  Collections.swap(numbers, 2 ,4 );  
 
String类 
String获取长度是.length()(要加括号)
String、StringBuilder类超详细笔记_stringbuilder可以用equalsignorecase-CSDN博客 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 重要:char  charAt(int  index) 返回指定索引处的 char 值。 int  indexOf(String ch) 返回指定字符第一次出现的字符串中的索引。    String  s  =  String.valueOf('c' );  - boolean  isEmpty ()  ,当且仅当, length()是 0  返回 true  int  lastIndexOf(int  ch) 返回指定字符最后一次出现的字符串中的索引。int  length ()  返回此字符串的长度。    String trim ()  去除两端的空格 String replace(CharSequence target, CharSequence replacement) 将此字符串中与文字目标序列匹配的每个子字符串替换为指定的文字替换序列。 String replaceAll(String regex, String replacement) 将给定替换的给定 regular expression匹配的此字符串的每个子字符串替换。 String[] split(String regex)  boolean  startsWith(String prefix) 测试此字符串是否以指定的前缀开头。String substring(int  beginIndex) 返回一个字符串,该字符串是此字符串的子字符串。 char [] toCharArray() 将此字符串转换为新的字符数组。String toLowerCase ()  使用默认语言环境的规则将此 String所有字符转换为小写。 String toUpperCase ()  使用默认语言环境的规则将此 String所有字符转换为大写。 比较大小的话     String c= "123" ; 	String  b  =  "123" ; 	c.compareTo(b); 或者     c.equals(b); 
 
字符类Chracter 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 Character.valueOf('I' ); Character.compare(char  x, char  y) 以数字方式比较两个 char 值。 Character.equals(Object obj) 将此对象与指定的对象进行比较。 Character.isDigit(char  ch) 确定指定的字符是否为数字。 Character.isLetter(char  ch) 确定指定的字符是否为字母。 Character.isLowerCase(char  ch) 确定指定的字符是否为小写字符。 Character.isUpperCase(char  ch) 确定指定的字符是否为大写字符。 Character.toString(char  c) 返回表示指定的 char 的 String对象。 Character.valueOf(char  c) 返回表示指定的 char 值的 Character实例。 Character.toLowerCase("A" ); 转为小写 Character.toUpperCase("a" ); 转为大写 char [] data = new  char [] {'a' ,'b' ,'c' };String  str  =  new  String (data);System.out.println(str);   
 
字符串构造器StringBuilder 
Java-修改 String 指定位置的字符最全方法总结(StringBuilder 和 StringBuffer 的使用以及区别)_string替换指定位置字符-CSDN博客 
String、StringBuffer与StringBuilder之间区别_string stringbuffer stringbuilder区别-CSDN博客 
可变字符串,StringBuilder对象的内容可以修改。
StringBuilder类的常用方法
append()方法 
使用append()方法可实现字符串的拼接操作,返回拼接后的StringBuilder对象。
 
reverse()方法 
使用reverse()方法可实现StringBuilder字符串的反转操作。
 
delete(int start, int end)方法 
删除字符串中指定索引范围为 [start,end) 的所有内容。
Java中大多数范围均为左闭右开区间。
1 2 3 4 StringBuilder  sb  =  new  StringBuilder ("hello" );sb.append("world" ); sb.delete(5 ,8 );   System.out.println(sb);   
 
 
insert(int start, 任意数据类型)方法 
在索引start处开始插入任意数据类型的内容。插入内容的起始索引是start。
1 2 3 4 5 StringBuilder  sb1  =  new  StringBuilder ("hello" );sb1.insert(2 ,77 ); System.out.println(sb1);   sb1.insert(3 ,"ooo" ); System.out.println(sb1);   
 
 
setCharAt(index,character)
1 sb.setCharAt(j,Character.toUpperCase(sb.charAt(j))); 
 
 
 
 
StringBuilder与String的相互转换 
1)String转为StringBuilder 
① 构造方法StringBuilder(String str)
 
 
1 2 StringBuilder  sb  =  new  StringBuilder ("hello" ); 
 
② 字符串拼接方法append(String str)
1 2 StringBuilder  sb  =  new  StringBuilder ();sb.append("123" ); 
 
2)StringBuilder转为String 
通过StringBuilder对象调用toString()方法
1 2 3 4 5 String  str  =  sb.toString();String、StringBuilder、StringBuffer的区别 String为不可变字符串类,StringBuilder、StringBuffer为可变字符串类。 StringBuilder类性能较高,但存在线程安全问题; StringBuffer类线程安全,但性能较差。 
 
双链表LinkedList 
1 2 3 4 5 6 7 8 boolean  isEmpty () int  size () boolean  contains (Object o)  void  addFirst (E e) E removeFirst ()   E getFirst/Last() int  indexOf ( E e) Collections.reverse(link);  
 
哈希表Hashmap 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 boolean  containsKey (Object key) 如果这个映射包含指定键映射,则返回true boolean  containsValue (Object value)  如果此映射将一个或多个键映射到指定值,则返回 true  。V get (Object key)  返回指定键映射到的值,如果此映射不包含键的映射,则返回 null  。 V put (K key, V value)  将指定的值与此映射中的指定键相关联。 V remove (Object key)  从此映射中删除指定键的映射(如果存在)。 int  size ()  返回此映射中键 - 值映射的数量。Collection<V> values ()  返回此映射中包含的值的Collection视图。 Set<K> keySet ()  返回此映射中包含的键的Set视图。 default  V getOrDefault (Object key, V defaultValue)  返回指定键映射到的值,如果此映射不包含键的映射,则返回 defaultValue 。这个方法继承自Map接口default  V putIfAbsent (K key, V value)  如果key存在则什么都不做,否则put(),并且返回当前值Set<Map.Entry<K,V>> entrySet() 返回此映射中包含的映射的Set视图。      Map<Integer, String> map = new  HashMap <>(); map.put(12836 , "小哈" );    map.put(15937 , "小啰" );    map.put(16750 , "小算" );    map.put(13276 , "小法" ); map.put(10583 , "小鸭" ); String  name  =  map.get(15937 );map.remove(10583 ); for  (Map.Entry <Integer, String> kv: map.entrySet()) {    System.out.println(kv.getKey() + " -> "  + kv.getValue()); } for  (int  key: map.keySet()) {    System.out.println(key); } for  (String val: map.values()) {    System.out.println(val); } 
 
哈希集合HashSet 
[【Java 基础篇】Java Set 详解-CSDN博客](https://blog.csdn.net/qq_21484461/article/details/131383848?ops_request_misc={"request_id"%3A"171015290416800180682690"%2C"scm"%3A"20140713.130102334.."}&request_id=171015290416800180682690&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-131383848-null-null.142^v99^pc_search_result_base2&utm_term=Java  set&spm=1018.2226.3001.4187)
不能保证集合迭代的顺序
1 2 3 boolean  add (E e)  如果指定的元素尚不存在,则将其添加到此集合中。boolean  remove (Object o)  如果存在,则从该集合中移除指定的元素。boolean  contains (Object o)  如果此set包含指定的元素,则返回 true  。
 
栈 Stack 
栈,后进先出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 Stack<Integer> stack = new  Stack <>(); stack.push(1 ); stack.push(3 ); stack.push(2 ); stack.push(5 ); stack.push(4 ); int  peek  =  stack.peek();int  pop  =  stack.pop();int  size  =  stack.size();boolean  isEmpty  =  stack.isEmpty();
 
队列Queue、双端队列Deque(都可用LinkedList来实例化,因为二者都是接口) 
队列,先进先出,Queue和Deque都是接口,而LinkedList类继承了这两个队列,可以是用LinkedList来实例化Queue或者Deque ,可以作为单向队列或者双向队列来使用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 Queue  q  =  new  LinkedList <>();void  add (int  index, E element)  将指定元素插入此列表中的指定位置。E element ()  检索但不删除此列表的头部(第一个元素)。 E get (int  index)  返回此列表中指定位置的元素。 int  indexOf (Object o)  返回此列表中第一次出现的指定元素的索引,如果此列表不包含该元素,则返回-1 。int  lastIndexOf (Object o)  返回此列表中指定元素最后一次出现的索引,如果此列表不包含该元素,则返回-1 。boolean  offer (E e)  将指定的元素添加为此列表的尾部(最后一个元素)。E peek ()  检索但不删除此列表的头部(第一个元素) E poll ()  检索并删除此列表的头部(第一个元素)。 E set (int  index, E element)  用指定的元素替换此列表中指定位置的元素。 Collections.reverse(queue)  int  size  =  queue.size();boolean  isEmpty  =  queue.isEmpty();
 
双端队列
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 Deque<Integer> deque = new  LinkedList <>(); deque.offerLast(2 );    deque.offerLast(5 ); deque.offerLast(4 ); deque.offerFirst(3 );   deque.offerFirst(1 ); int  peekFirst  =  deque.peekFirst();  int  peekLast  =  deque.peekLast();    int  popFirst  =  deque.pollFirst();  int  popLast  =  deque.pollLast();    int  size  =  deque.size();boolean  isEmpty  =  deque.isEmpty();
 
…
1 2 3 4 LinkedList可以作为堆栈使用,并且在类中实现了对应的方法 E pop ()  弹出此列表所代表的堆栈中的元素。 void  push (E e)  将元素推送到此列表所表示的堆栈上。
 
优先队列(作为堆来用) 
默认小顶堆,但如果是数据结构就还是要重写comparator
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 import  java.util.PriorityQueue;PriorityQueue<Integer> minHeap = new  PriorityQueue <>(); minHeap.peek(); minHeap.poll();(会弹出) minHeap.add(); minHeap.offer(); Queue<Integer> integerPriorityQueue = new  PriorityQueue <>(7 ); Queue<Customer> customerPriorityQueue = new  PriorityQueue <>(idComparator); public  static  Comparator<Customer> idComparator = new  Comparator <Customer>(){    public  int  compare (Customer c1, Customer c2)  {         return  (int ) (c1.getId() - c2.getId());         }     }; class  idComparator  implements  Comparator {    @Override      public  int  compare (Customer c1, Customer c2) {         return  (int )(c1.getId()-c2.getId)());     } } 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 Queue<Integer> minHeap = new  PriorityQueue <>(); Queue<Integer> maxHeap = new  PriorityQueue <>((a, b) -> b - a); maxHeap.offer(1 ); maxHeap.offer(3 ); maxHeap.offer(2 ); maxHeap.offer(5 ); maxHeap.offer(4 ); int  peek  =  maxHeap.peek(); peek = maxHeap.poll();  peek = maxHeap.poll();  peek = maxHeap.poll();  peek = maxHeap.poll();  peek = maxHeap.poll();  int  size  =  maxHeap.size();boolean  isEmpty  =  maxHeap.isEmpty();minHeap = new  PriorityQueue <>(Arrays.asList(1 , 3 , 2 , 5 , 4 )); 
 
数学库 
1 2 3 4 5 6 7 8 9 Math.ceil(3.3 );  Math.floor(3.3 );  Math.round(3.4 );  Math.pow(3 ,2 )  Math.abs(-1 );  Math.max(9999 ,10000 ); Math.min(9999 ,10000 ); Math.ramdom();  Math.sqrt(3.644 );  
 
算法 
排序 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 import  java.util.Arrays;public  class  MergeSort {    public  static  void  mergeSort (int []arr, int  l, int  r) {         if  (l>=r)return  ;         int  mid  =  l+(r-l)/2 ;         mergeSort(arr,l,mid);         mergeSort(arr,mid+1 ,r);         merge(arr,l,mid,r);     }     public  static  void  merge (int [] arr, int  l ,int  mid,int  r) {         int  temp[] = new  int [r-l+1 ];         int  left  =  l;         int  right  =  mid+1 ;         int  start  =  0 ;         while (left<=mid&& right<=r){             if  (arr[left]<arr[right]){                 temp[start++] = arr[left++];             }else {                 temp[start++] = arr[right++];             }         }         while (left<=mid){             temp[start++] = arr[left++];         }         while (right<=r){             temp[start++] = arr[right++];         }         for (int  i=0 ;i<temp.length;i++){                 arr[l+i] = temp[i];         }      }      public  static  void  main (String[] args) {         int  nums[] = new  int []{             1 ,4 ,2 ,6 ,9 ,3 ,5 ,8 ,7          };         mergeSort(nums,0 ,nums.length-1 );         System         .out.println(Arrays.toString(nums));      } } 
 
图 
邻接矩阵
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 class  GraphAdjMat  {    List<Integer> vertices;      List<List<Integer>> adjMat;           public  GraphAdjMat (int [] vertices, int [][] edges)  {         this .vertices = new  ArrayList <>();         this .adjMat = new  ArrayList <>();                  for  (int  val : vertices) {             addVertex(val);         }                           for  (int [] e : edges) {             addEdge(e[0 ], e[1 ]);         }     }          public  int  size ()  {         return  vertices.size();     }          public  void  addVertex (int  val)  {         int  n  =  size();                  vertices.add(val);                  List<Integer> newRow = new  ArrayList <>(n);         for  (int  j  =  0 ; j < n; j++) {             newRow.add(0 );         }         adjMat.add(newRow);                  for  (List<Integer> row : adjMat) {             row.add(0 );         }     }          public  void  removeVertex (int  index)  {         if  (index >= size())             throw  new  IndexOutOfBoundsException ();                  vertices.remove(index);                  adjMat.remove(index);                  for  (List<Integer> row : adjMat) {             row.remove(index);         }     }               public  void  addEdge (int  i, int  j)  {                  if  (i < 0  || j < 0  || i >= size() || j >= size() || i == j)             throw  new  IndexOutOfBoundsException ();                  adjMat.get(i).set(j, 1 );         adjMat.get(j).set(i, 1 );     }               public  void  removeEdge (int  i, int  j)  {                  if  (i < 0  || j < 0  || i >= size() || j >= size() || i == j)             throw  new  IndexOutOfBoundsException ();         adjMat.get(i).set(j, 0 );         adjMat.get(j).set(i, 0 );     }          public  void  print ()  {         System.out.print("顶点列表 = " );         System.out.println(vertices);         System.out.println("邻接矩阵 =" );         PrintUtil.printMatrix(adjMat);     } } 
 
邻接表的BFS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 List<Vertex> graphBFS (GraphAdjList graph, Vertex startVet)  {          List<Vertex> res = new  ArrayList <>();          Set<Vertex> visited = new  HashSet <>();     visited.add(startVet);          Queue<Vertex> que = new  LinkedList <>();     que.offer(startVet);          while  (!que.isEmpty()) {         Vertex  vet  =  que.poll();          res.add(vet);                              for  (Vertex adjVet : graph.adjList.get(vet)) {             if  (visited.contains(adjVet))                 continue ;                     que.offer(adjVet);                visited.add(adjVet);          }     }          return  res; } 
 
邻接表的DFS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 void  dfs (GraphAdjList graph, Set<Vertex> visited, List<Vertex> res, Vertex vet)  {    res.add(vet);          visited.add(vet);           for  (Vertex adjVet : graph.adjList.get(vet)) {         if  (visited.contains(adjVet))             continue ;                   dfs(graph, visited, res, adjVet);     } } List<Vertex> graphDFS (GraphAdjList graph, Vertex startVet)  {          List<Vertex> res = new  ArrayList <>();          Set<Vertex> visited = new  HashSet <>();     dfs(graph, visited, res, startVet);     return  res; } 
 
Floyd 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 public  class  MatrixUDG  {    private  int  mEdgNum;             private  char [] mVexs;            private  int [][] mMatrix;         private  static  final  int  INF  =  Integer.MAX_VALUE;        ... } public  void  floyd (int [][] path, int [][] dist)  {         for  (int  i  =  0 ; i < mVexs.length; i++) {         for  (int  j  =  0 ; j < mVexs.length; j++) {             dist[i][j] = mMatrix[i][j];                 path[i][j] = j;                         }     }          for  (int  k  =  0 ; k < mVexs.length; k++) {         for  (int  i  =  0 ; i < mVexs.length; i++) {             for  (int  j  =  0 ; j < mVexs.length; j++) {                                  int  tmp  =  (dist[i][k]==INF || dist[k][j]==INF) ? INF : (dist[i][k] + dist[k][j]);                 if  (dist[i][j] > tmp) {                                          dist[i][j] = tmp;                                          path[i][j] = path[i][k];                 }             }         }     }          System.out.printf("floyd: \n" );     for  (int  i  =  0 ; i < mVexs.length; i++) {         for  (int  j  =  0 ; j < mVexs.length; j++)             System.out.printf("%2d  " , dist[i][j]);         System.out.printf("\n" );     } } 
 
迪杰斯特拉 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 public  class  MatrixUDG  {      private  int  mEdgNum;             private  char [] mVexs;            private  int [][] mMatrix;         private  static  final  int  INF  =  Integer.MAX_VALUE;          ... } public  void  dijkstra (int  vs, int [] prev, int [] dist)  {         boolean [] flag = new  boolean [mVexs.length];            for  (int  i  =  0 ; i < mVexs.length; i++) {         flag[i] = false ;                   prev[i] = 0 ;                       dist[i] = mMatrix[vs][i];       }            flag[vs] = true ;     dist[vs] = 0 ;            int  k=0 ;     for  (int  i  =  1 ; i < mVexs.length; i++) {                           int  min  =  INF;         for  (int  j  =  0 ; j < mVexs.length; j++) {             if  (flag[j]==false  && dist[j]<min) {                 min = dist[j];                 k = j;             }         }                  flag[k] = true ;                             for  (int  j  =  0 ; j < mVexs.length; j++) {             int  tmp  =  (mMatrix[k][j]==INF ? INF : (min + mMatrix[k][j]));             if  (flag[j]==false  && (tmp<dist[j]) ) {                 dist[j] = tmp;                 prev[j] = k;             }         }     }            System.out.printf("dijkstra(%c): \n" , mVexs[vs]);     for  (int  i=0 ; i < mVexs.length; i++)         System.out.printf("  shortest(%c, %c)=%d\n" , mVexs[vs], mVexs[i], dist[i]); } 
 
Leetcode 133.克隆图 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 class  Solution  {    Map<Node,Node>visitedMap=new  HashMap ();     public  Node cloneGraph (Node node)  {         if  (node==null )return  null ;         if  (!visitedMap.containsKey(node)){             int  val  =  node.val;             Node  temp  =  new  Node (val,new  ArrayList ());             visitedMap.put(node,temp);         }else {             return  visitedMap.get(node);         }         Node  ans  =  visitedMap.get(node);         for  (Node node1:node.neighbors){             ans.neighbors.add(cloneGraph(node1));         }         return  ans;     } } 
 
Leetcode 399.除法求值(并查集,一遍查询一边修改) 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 import  java.util.HashMap;import  java.util.List;import  java.util.Map;public  class  Solution  {    public  double [] calcEquation(List<List<String>> equations, double [] values, List<List<String>> queries) {         int  equationsSize  =  equations.size();         UnionFind  unionFind  =  new  UnionFind (2  * equationsSize);                  Map<String, Integer> hashMap = new  HashMap <>(2  * equationsSize);         int  id  =  0 ;         for  (int  i  =  0 ; i < equationsSize; i++) {             List<String> equation = equations.get(i);             String  var1  =  equation.get(0 );             String  var2  =  equation.get(1 );             if  (!hashMap.containsKey(var1)) {                 hashMap.put(var1, id);                 id++;             }             if  (!hashMap.containsKey(var2)) {                 hashMap.put(var2, id);                 id++;             }             unionFind.union(hashMap.get(var1), hashMap.get(var2), values[i]);         }                  int  queriesSize  =  queries.size();         double [] res = new  double [queriesSize];         for  (int  i  =  0 ; i < queriesSize; i++) {             String  var1  =  queries.get(i).get(0 );             String  var2  =  queries.get(i).get(1 );             Integer  id1  =  hashMap.get(var1);             Integer  id2  =  hashMap.get(var2);             if  (id1 == null  || id2 == null ) {                 res[i] = -1.0d ;             } else  {                 res[i] = unionFind.isConnected(id1, id2);             }         }         return  res;     }     private  class  UnionFind  {         private  int [] parent;                  private  double [] weight;         public  UnionFind (int  n)  {             this .parent = new  int [n];             this .weight = new  double [n];             for  (int  i  =  0 ; i < n; i++) {                 parent[i] = i;                 weight[i] = 1.0d ;             }         }         public  void  union (int  x, int  y, double  value)  {             int  rootX  =  find(x);             int  rootY  =  find(y);             if  (rootX == rootY) {                 return ;             }             parent[rootX] = rootY;           	             weight[rootX] = weight[y] * value / weight[x];         }                  public  int  find (int  x)  {             if  (x != parent[x]) {                 int  origin  =  parent[x];                 parent[x] = find(parent[x]);                 weight[x] *= weight[origin];             }             return  parent[x];         }         public  double  isConnected (int  x, int  y)  {             int  rootX  =  find(x);             int  rootY  =  find(y);             if  (rootX == rootY) {                 return  weight[x] / weight[y];             } else  {                 return  -1.0d ;             }         }     } } 
 
Leetcode 207.课程表 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 class  Solution  {    public  boolean  canFinish (int  numCourses, int [][] prerequisites)  {         int  numOfRelations  =  prerequisites.length;         int  inDegree[] = new  int [numCourses];         Map<Integer,List<Integer>>map = new  HashMap ();         for  (int  i=0 ;i<numOfRelations;i++){             int  pre  =  prerequisites[i][0 ];             int  after  =  prerequisites[i][1 ];             inDegree[after]++;             List<Integer>list = map.getOrDefault(pre,new  ArrayList <Integer>());             list.add(after);             map.put(pre,list);         }         Queue<Integer>q = new  LinkedList ();         for  (int  i=0 ;i<numCourses;i++){             if  (inDegree[i]==0 )q.add(i);         }         while (!q.isEmpty()){             int  pre  =  q.poll();             List<Integer>after = map.get(pre);             if  (after!=null )             for  (int  num:after){                 inDegree[num]--;                 if  (inDegree[num]==0 )q.add(num);             }         }         for  (int  i=0 ;i<numCourses;i++){             if  (inDegree[i]!=0 )return  false ;         }         return  true ;     } } 
 
Leetcode 210.课程表2 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 class  Solution  {    public  int [] findOrder(int  numCourses, int [][] prerequisites) {         int  numOfRelations  =  prerequisites.length;         int  inDegree[] = new  int [numCourses];         Map<Integer,List<Integer>>map = new  HashMap ();         for  (int  i=0 ;i<numOfRelations;i++){             int  after  =  prerequisites[i][0 ];             int  pre  =  prerequisites[i][1 ];             inDegree[after]++;             List<Integer>list = map.getOrDefault(pre,new  ArrayList <Integer>());             list.add(after);             map.put(pre,list);         }         Queue<Integer>q = new  LinkedList ();         for  (int  i=0 ;i<numCourses;i++){             if  (inDegree[i]==0 )q.add(i);         }         int  ans[]=new  int [numCourses];         int  start  =  0 ;         while (!q.isEmpty()){             int  pre  =  q.poll();             ans[start] = pre;             start++;             List<Integer>after = map.get(pre);             if  (after!=null ){                     for  (int  num:after){                 inDegree[num]--;                 if  (inDegree[num]==0 )q.add(num);                 }             }                      }         for  (int  i=0 ;i<numCourses;i++){             if  (inDegree[i]!=0 )return  new  int []{};         }         return  ans;     }      } 
 
Leetcode 909.蛇梯棋 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 class  Solution  {    public  int  snakesAndLadders (int [][] board)  {                  if (board == null  || board.length == 0  || board[0 ] == null  || board[0 ].length == 0 ){             return  0 ;         }                  int  rowNum  =  board.length;         int  colNum  =  board[0 ].length;         boolean  isRight  =  true ;                  int [] nums = new  int [rowNum * rowNum + 1 ];         int  index  =  1 ;         for (int  i  =  rowNum - 1 ; i >= 0 ; i--){             if (isRight){                 for (int  j  =  0 ; j < colNum; j++){                     nums[index++] = board[i][j];                 }             }             else {                 for (int  j  =  colNum - 1 ; j >= 0 ; j--){                     nums[index++] = board[i][j];                 }             }             isRight = !isRight;         }                  Queue<Integer> queue = new  LinkedList <>();         queue.offer(1 );                  Map<Integer, Integer> distanceMap = new  HashMap <>();         distanceMap.put(1 , 0 );         while (!queue.isEmpty()){             int  curIndex  =  queue.poll();             int  step  =  distanceMap.get(curIndex);                          if (curIndex == rowNum * rowNum){                 return  step;             }             for (int  i  =  1 ; i <= 6 ; i++){                 int  newIndex  =  curIndex + i;                                  if (newIndex <= 0  || newIndex > rowNum * rowNum){                     continue ;                 }                                  if (nums[newIndex] != -1 ){                     newIndex = nums[newIndex];                 }                                  if (distanceMap.containsKey(newIndex)){                     continue ;                 }                                  queue.offer(newIndex);                                                   distanceMap.put(newIndex, step + 1 );             }         }         return  -1 ;     } } 
 
回溯问题 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 void  backtrack (State state, List<Choice> choices, List<State> res)  {         if  (isSolution(state)) {                  recordSolution(state, res);                  return ;     }          for  (Choice choice : choices) {                  if  (isValid(state, choice)) {                          makeChoice(state, choice);             backtrack(state, choices, res);                          undoChoice(state, choice);         }     } } 
 
全排列问题 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 class  Solution  {    public  List<List<Integer>> permute (int [] nums)  {         List<List<Integer>> res = new  ArrayList <List<Integer>>();         List<Integer> output = new  ArrayList <Integer>();         for  (int  num : nums) {             output.add(num);         }         int  n  =  nums.length;         backtrack(n, output, res, 0 );         return  res;     }     public  void  backtrack (int  n, List<Integer> output, List<List<Integer>> res, int  first)  {                  if  (first == n) {             res.add(new  ArrayList <Integer>(output));         }         for  (int  i  =  first; i < n; i++) {                          Collections.swap(output, first, i);                          backtrack(n, output, res, first + 1 );                          Collections.swap(output, first, i);         }     } } 
 
子集和问题 
类似于全排列问题,我们可以把子集的生成过程想象成一系列选择的结果,并在选择过程中实时更新“元素和”,当元素和等于 target 时,就将子集记录至结果列表。
而与全排列问题不同的是,本题集合中的元素可以被无限次选取 ,因此无须借助 selected 布尔列表来记录元素是否已被选择。我们可以对全排列代码进行小幅修改,初步得到解题代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 void  backtrack (List<Integer> state, int  target, int  total, int [] choices, List<List<Integer>> res)  {         if  (total == target) {         res.add(new  ArrayList <>(state));         return ;     }          for  (int  i  =  0 ; i < choices.length; i++) {                  if  (total + choices[i] > target) {             continue ;         }                  state.add(choices[i]);                  backtrack(state, target, total + choices[i], choices, res);                  state.remove(state.size() - 1 );     } } List<List<Integer>> subsetSumINaive (int [] nums, int  target)  {     List<Integer> state = new  ArrayList <>();      int  total  =  0 ;      List<List<Integer>> res = new  ArrayList <>();      backtrack(state, target, total, nums, res);     return  res; } 
 
但这样的问题是,其在进行选取的时候,会造成重复,解决办法是先排序
在开启搜索前,先将数组 nums 排序。在遍历所有选择时,当子集和超过 target 时直接结束循环 ,因为后边的元素更大,其子集和一定超过 target 。 
省去元素和变量 total ,通过在 target 上执行减法来统计元素和 ,当 target 等于 0 时记录解。 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 void  backtrack (List<Integer> state, int  target, int [] choices, int  start, List<List<Integer>> res)  {         if  (target == 0 ) {         res.add(new  ArrayList <>(state));         return ;     }               for  (int  i  =  start; i < choices.length; i++) {                           if  (target - choices[i] < 0 ) {             break ;         }                  state.add(choices[i]);                  backtrack(state, target - choices[i], choices, i, res);                  state.remove(state.size() - 1 );     } } List<List<Integer>> subsetSumI (int [] nums, int  target)  {     List<Integer> state = new  ArrayList <>();      Arrays.sort(nums);      int  start  =  0 ;      List<List<Integer>> res = new  ArrayList <>();      backtrack(state, target, nums, start, res);     return  res; } 
 
N皇后问题(经典) 
13.4  N 皇后问题 - Hello 算法 (hello-algo.com) 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 void  backtrack (int  row, int  n, List<List<String>> state, List<List<List<String>>> res,         boolean [] cols, boolean [] diags1, boolean [] diags2)  {         if  (row == n) {         List<List<String>> copyState = new  ArrayList <>();         for  (List<String> sRow : state) {             copyState.add(new  ArrayList <>(sRow));         }         res.add(copyState);         return ;     }          for  (int  col  =  0 ; col < n; col++) {                  int  diag1  =  row - col + n - 1 ;         int  diag2  =  row + col;                  if  (!cols[col] && !diags1[diag1] && !diags2[diag2]) {                          state.get(row).set(col, "Q" );             cols[col] = diags1[diag1] = diags2[diag2] = true ;                          backtrack(row + 1 , n, state, res, cols, diags1, diags2);                          state.get(row).set(col, "#" );             cols[col] = diags1[diag1] = diags2[diag2] = false ;         }     } } List<List<List<String>>> nQueens (int  n)  {          List<List<String>> state = new  ArrayList <>();     for  (int  i  =  0 ; i < n; i++) {         List<String> row = new  ArrayList <>();         for  (int  j  =  0 ; j < n; j++) {             row.add("#" );         }         state.add(row);     }     boolean [] cols = new  boolean [n];      boolean [] diags1 = new  boolean [2  * n - 1 ];      boolean [] diags2 = new  boolean [2  * n - 1 ];      List<List<List<String>>> res = new  ArrayList <>();     backtrack(0 , n, state, res, cols, diags1, diags2);     return  res; } 
 
2024.09.04蔚来 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 import  java.util.Scanner;public  class  Main  {    public  static  boolean  getAns (int [][] matrix, int [][] ans, boolean  flag)  {         int  m  =  matrix.length;         int  n  =  matrix[0 ].length;                  int  currentX  =  0 ;         int  currentY  =  0 ;         int  steps[][] = new  int [4 ][2 ];         steps[0 ][0 ] = 0 ; steps[0 ][1 ] = 1 ;         steps[1 ][0 ] = 1 ; steps[1 ][1 ] = 0 ;         steps[2 ][0 ] = 0 ; steps[2 ][1 ] = -1 ;         steps[3 ][0 ] = -1 ; steps[3 ][1 ] = 0 ;                  if  (matrix[0 ][0 ] == 1 ) return  false ;         ans[0 ][0 ] = 1 ;                  boolean  visited[][] = new  boolean [m][n];         for  (int  i  =  0 ; i < m; i++) {             for  (int  j  =  0 ; j < n; j++) {                 visited[i][j] = false ;             }         }         return  backtrace(matrix, visited, currentX, currentY, m, n, flag, steps, ans);     }     public  static  boolean  backtrace (int [][] matrix, boolean [][] visited, int  currentX, int  currentY, int  m, int  n, boolean  flag, int [][] steps, int [][] ans)  {         if  (currentY < 0  || currentY >= n || currentX < 0  || currentX >= m) return  false ;         for  (int  j  =  0 ; j < 4 ; j++) {             int  tempCurrentX  =  currentX + steps[j][0 ];             int  tempCurrentY  =  currentY + steps[j][1 ];             if  (tempCurrentX < 0  || tempCurrentX >= m || tempCurrentY < 0  || tempCurrentY >= n || visited[tempCurrentX][tempCurrentY] || matrix[tempCurrentX][tempCurrentY] == 1 ) {                 continue ;             } else  {                 if  (tempCurrentX == m - 1  && tempCurrentY == n - 1 ) {                     flag = true ;                     ans[tempCurrentX][tempCurrentY] = 1 ;                     return  true ;                 }                 visited[tempCurrentX][tempCurrentY] = true ;                 ans[tempCurrentX][tempCurrentY] = 1 ;                 if  (backtrace(matrix, visited, tempCurrentX, tempCurrentY, m, n, flag, steps, ans)) {                     return  true ;                 }                 ans[tempCurrentX][tempCurrentY] = 0 ;                 visited[tempCurrentX][tempCurrentY] = false ;             }         }         return  false ;     }     public  static  void  main (String[] args)  {         boolean  flag  =  false ;         int  matrix[][] = new  int [3 ][3 ];         matrix[0 ][1 ] = 1 ;         matrix[0 ][2 ] = 1 ;         int  ans[][] = new  int [3 ][3 ];         flag = getAns(matrix, ans, flag);         if  (flag) {             for  (int  i  =  0 ; i < 3 ; i++) {                 for  (int  j  =  0 ; j < 3 ; j++) {                     System.out.print(ans[i][j] + " " );                 }                 System.out.println();             }         } else  {             System.out.println("No path found." );         }     } } 
 
Leetcode 77.组合 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 class  Solution  {    List<Integer> temp = new  ArrayList <Integer>();     List<List<Integer>> ans = new  ArrayList <List<Integer>>();     public  List<List<Integer>> combine (int  n, int  k)  {         dfs(1 , n, k);         return  ans;     }     public  void  dfs (int  cur, int  n, int  k)  {                  if  (temp.size() + (n - cur + 1 ) < k) {             return ;         }                  if  (temp.size() == k) {             ans.add(new  ArrayList <Integer>(temp));             return ;         }                  temp.add(cur);         dfs(cur + 1 , n, k);         temp.remove(temp.size() - 1 );                  dfs(cur + 1 , n, k);     } } 
 
动态规划 
记忆化搜索 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 int  dfs (int  i, int [] mem)  {         if  (i == 1  || i == 2 )         return  i;          if  (mem[i] != -1 )         return  mem[i];          int  count  =  dfs(i - 1 , mem) + dfs(i - 2 , mem);          mem[i] = count;     return  count; } int  climbingStairsDFSMem (int  n)  {         int [] mem = new  int [n + 1 ];     Arrays.fill(mem, -1 );     return  dfs(n, mem); } 
 
01背包 
暴力搜索 O(2^n)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 int  knapsackDFS (int [] wgt, int [] val, int  i, int  c)  {         if  (i == 0  || c == 0 ) {         return  0 ;     }          if  (wgt[i - 1 ] > c) {         return  knapsackDFS(wgt, val, i - 1 , c);     }          int  no  =  knapsackDFS(wgt, val, i - 1 , c);     int  yes  =  knapsackDFS(wgt, val, i - 1 , c - wgt[i - 1 ]) + val[i - 1 ];          return  Math.max(no, yes); } 
 
空间优化加动态规划
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 int  knapsackDPComp (int [] wgt, int [] val, int  cap)  {    int  n  =  wgt.length;          int [] dp = new  int [cap + 1 ];          for  (int  i  =  1 ; i <= n; i++) {                  for  (int  c  =  cap; c >= 1 ; c--) {             if  (wgt[i - 1 ] <= c) {                                  dp[c] = Math.max(dp[c], dp[c - wgt[i - 1 ]] + val[i - 1 ]);             }         }     }     return  dp[cap]; } 
 
完全背包 
空间优化加动态规划
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 int  unboundedKnapsackDPComp (int [] wgt, int [] val, int  cap)  {    int  n  =  wgt.length;          int [] dp = new  int [cap + 1 ];          for  (int  i  =  1 ; i <= n; i++) {         for  (int  c  =  1 ; c <= cap; c++) {             if  (wgt[i - 1 ] > c) {                                  dp[c] = dp[c];             } else  {                                  dp[c] = Math.max(dp[c], dp[c - wgt[i - 1 ]] + val[i - 1 ]);             }         }     }     return  dp[cap]; } 
 
Leetcode 322.零钱兑换 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class  Solution  {    public  int  coinChange (int [] coins, int  amount)  {         int  types  =  coins.length;         int  dp[] = new  int [amount+1 ];         for  (int  i  =  0 ;i<=amount;i++){             dp[i]=amount+1 ;         }         dp[0 ]=0 ;         for  (int  i  =  0 ;i<types;i++){             for  (int  j=0 ;j<=amount;j++){                 if  (j>=coins[i]){                      if (dp[j-coins[i]]+1 <dp[j]){                         dp[j] = dp[j-coins[i]]+1 ;                     }                 }else {                     continue ;                 }             }         }         if  (dp[amount]==amount+1 )return  -1 ;         return  dp[amount];     } } 
 
零钱兑换问题2 
凑硬币
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 int  coinChangeIIDP (int [] coins, int  amt)  {    int  n  =  coins.length;          int [][] dp = new  int [n + 1 ][amt + 1 ];          for  (int  i  =  0 ; i <= n; i++) {         dp[i][0 ] = 1 ;     }          for  (int  i  =  1 ; i <= n; i++) {         for  (int  a  =  1 ; a <= amt; a++) {             if  (coins[i - 1 ] > a) {                                  dp[i][a] = dp[i - 1 ][a];             } else  {                                  dp[i][a] = dp[i - 1 ][a] + dp[i][a - coins[i - 1 ]];             }         }     }     return  dp[n][amt]; } 
 
加空间优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 int  coinChangeIIDPComp (int [] coins, int  amt)  {    int  n  =  coins.length;          int [] dp = new  int [amt + 1 ];     dp[0 ] = 1 ;          for  (int  i  =  1 ; i <= n; i++) {         for  (int  a  =  1 ; a <= amt; a++) {             if  (coins[i - 1 ] > a) {                                  dp[a] = dp[a];             } else  {                                  dp[a] = dp[a] + dp[a - coins[i - 1 ]];             }         }     }     return  dp[amt]; } 
 
编辑距离问题 
14.6  编辑距离问题 - Hello 算法 (hello-algo.com) 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 package  datastructure.dp;public  class  Levenshtein  {    public  static  int  distance (String a, String b)  {          int  length1  =  a.length();          int  length2  =  b.length();          int  dp[][] = new  int [length1+1 ][length2+1 ];          for  (int  i=1 ;i<=length1;i++){              dp[i][0 ]=i;          }          for  (int  j=1 ;j<=length2;j++){              dp[0 ][j]=j;          }          for  (int  i  =  1  ;i<=length1;i++){              for  (int  j=1 ;j<=length2;j++){                  if  (a.charAt(i-1 )==b.charAt(j-1 )){                     dp[i][j]=dp[i-1 ][j-1 ];                  }else {                      dp[i][j]=Math.min(dp[i-1 ][j-1 ],Math.min(dp[i-1 ][j],dp[i][j-1 ]))+1 ;                  }              }          }          return  dp[length1][length2];      }      public  static  void  main (String[] args)  {           String  s1  =  "kitten" ;           String  s2  =  "sitting" ;           int  ans  =  distance(s1,s2);           System.out.println(ans);       } } 
 
Leetcode 198.打家劫舍 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class  Solution  {    public  int  rob (int [] nums)  {         int  length  =  nums.length;         if  (length == 1 )return  nums[0 ];         int  dp [] = new  int  [length];         dp[0 ] = nums[0 ];         for  (int  i=1 ; i< length;i++){             int  before  =  i-2 ;             if  (i==1 ){                 dp[i]=Math.max(nums[i],nums[i-1 ]);                 continue ;             }             else {                 dp[i]=Math.max(dp[i-1 ],dp[i-2 ]+nums[i]);             }         }         return  dp[length-1 ];     } } 
 
Leetcode 139.单词拆分 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class  Solution  {    public  boolean  wordBreak (String s, List<String> wordDict)  {         int  length  =  s.length();         boolean  dp[] = new  boolean [length+1 ];         dp[0 ]=true ;         for (int  i  =  0 ;i<length;i++){             for  (int  j=i+1 ;j<length+1 ;j++){                 if  (dp[i]&&wordDict.contains(s.substring(i,j))){                     dp[j]=true ;                 }             }         }         return  dp[length];     } } 
 
Leetcode 300.最长递增子序列 
解法1:一种特殊思想
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 class  Solution  {    public  int  lengthOfLIS (int [] nums)  {         List<Integer> ans = new  ArrayList ();         int  length  =  nums.length;         for  (int  i=0 ;i<length;i++){             if  (ans.size()==0 ||nums[i]>ans.get(ans.size()-1 )){                 ans.add(nums[i]);             }else {                 int  index  =  findSmallIndex(ans,nums[i]);                 if  (index!=-1 ){                     ans.set(index,nums[i]);                 }             }         }         return  ans.size();     }     public  int  findSmallIndex (List<Integer> ans,int  num) {         int  length   =  ans.size();         for  (int  i=0 ;i<length;i++){             if  (ans.get(i)>=num){                 return  i;             }         }         return  -1 ;     } } 
 
解法2:动态规划
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class  Solution  {    public  int  lengthOfLIS (int [] nums)  {         int  length  =  nums.length;         if  (length==1 )return  1 ;         int  dp[]= new  int [length];         for  (int  i=0 ;i<length;i++){             dp[i]=1 ;         }         int  ans=1 ;         for  (int  i=1 ;i<length;i++){             for  (int  j=0 ;j<i;j++){                 if (nums[i]>nums[j]){                     dp[i]=Math.max(dp[i],dp[j]+1 );                                      }             }             ans = Math.max(dp[i],ans);         }         return  ans;     } } 
 
Leetcode 120.三角形最小路径和 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class  Solution  {    public  int  minimumTotal (List<List<Integer>> triangle)  {         int  depth  =  triangle.size();         int  dp[][]=new  int [depth][depth];         dp[0 ][0 ]=triangle.get(0 ).get(0 );         if  (depth==1 ){             return  dp[0 ][0 ];         }         for  (int  i=1 ;i<depth;i++){             dp[i][0 ]=dp[i-1 ][0 ]+triangle.get(i).get(0 );             for  (int  j=1 ;j<triangle.get(i).size()-1 ;j++){                 dp[i][j]=Math.min(dp[i-1 ][j-1 ]+triangle.get(i).get(j),dp[i-1 ][j]+triangle.get(i).get(j));             }             dp[i][triangle.get(i).size()-1 ]=dp[i-1 ][triangle.get(i-1 ).size()-1 ]+triangle.get(i).get(triangle.get(i).size()-1 );         }         int  ans  =  Integer.MAX_VALUE;         for (int  i=0 ;i<triangle.get(depth-1 ).size();i++){             ans = Math.min(dp[depth-1 ][i],ans);         }         return  ans;     } } 
 
Leetcode 221.最大正方形 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 class  Solution  {    public  int  maximalSquare (char [][] matrix)  {         int  length  =  matrix.length;         int  length2  =  matrix[0 ].length;         int  ans  =  0 ;         int  dp[][] = new  int  [length][length2];         for  (int  i=0 ;i<length;i++){             for (int  j=0 ;j<length2;j++){                 if  (matrix[i][j]=='1' ){                     if  (i==0 ||j==0 ){                         dp[i][j]=1 ;                         ans = Math.max(ans,dp[i][j]);                     }else {                         dp[i][j]=1 +getSmallest(dp[i-1 ][j],dp[i-1 ][j-1 ],dp[i][j-1 ]);                         ans = Math.max(ans,dp[i][j]);                     }                   }else {                     dp[i][j]=0 ;                 }             }         }         return  ans*ans;     }     public  int  getSmallest (int  a,int  b,int  c) {         if  (a>b){             if  (b>c)return  c;             else  return  b;         }else {             if  (a>c)return  c;             else  return  a;         }     } } 
 
Leetcode 72.编辑距离 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 class  Solution  {    public  int  minDistance (String word1, String word2)  {         int  length1  =  word1.length();         int  length2  =  word2.length();         int  dp[][] = new  int [length1+1 ][length2+1 ];         dp[0 ][0 ]=0 ;         if  (length1*length2==0 )return  length1+length2;         if  (length1>1 ){             for  (int  i=1 ;i<=length1;i++){             dp[i][0 ]=dp[i-1 ][0 ]+1 ;             }         }         if  (length2>1 ){             for  (int  j=1 ;j<=length2;j++){             dp[0 ][j]=dp[0 ][j-1 ]+1 ;             }         }                  for  (int  i=1 ;i<=length1;i++){             for  (int  j=1 ;j<=length2;j++){                 if  (word1.charAt(i-1 )==word2.charAt(j-1 )){                                          dp[i][j]= getSmallest(dp[i-1 ][j-1 ]-1 ,dp[i-1 ][j],dp[i][j-1 ])+1 ;                 }else {                     dp[i][j]= 1 +getSmallest(dp[i-1 ][j-1 ],dp[i][j-1 ],dp[i-1 ][j]);                 }             }         }         return  dp[length1][length2];     }     public  int  getSmallest (int  a,int  b,int  c) {         if  (a>b){             if  (b>c)return  c;             return  b;         }else {             if  (a>c)return  c;             return  a;         }     } } 
 
贪心 
一般情况下,贪心算法的适用情况分以下两种。
可以保证找到最优解 :贪心算法在这种情况下往往是最优选择,因为它往往比回溯、动态规划更高效。 
可以找到近似最优解 :贪心算法在这种情况下也是可用的。对于很多复杂问题来说,寻找全局最优解非常困难,能以较高效率找到次优解也是非常不错的。 
 
贪心问题的解决流程大体可分为以下三步。
问题分析 :梳理与理解问题特性,包括状态定义、优化目标和约束条件等。这一步在回溯和动态规划中都有涉及。 
确定贪心策略 :确定如何在每一步中做出贪心选择。这个策略能够在每一步减小问题的规模,并最终解决整个问题。 
正确性证明 :通常需要证明问题具有贪心选择性质和最优子结构。这个步骤可能需要用到数学证明,例如归纳法或反证法等。 
 
加油站 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 class  Solution  {    public  int  canCompleteCircuit (int [] gas, int [] cost)  {         int  n  =  gas.length;         int  sumGas  =  0 ;         int  sumCost  =  0 ;         for  (int  i  =  0 ; i < n; i++) {             sumCost += cost[i];             sumGas += gas[i];         }         if  (sumCost > sumGas)             return  -1 ;         for  (int  i  =  0 ; i < n; i++) {             int  rest  =  0 ;             int  hasPassed  =  0 ;             for  (int  j  =  i; hasPassed < n; j++) {                 if  (j == n)                     j = 0 ;                 rest += gas[j];                 if  (rest >= cost[j]) {                     rest -= cost[j];                     hasPassed++;                 } else  {                     i = j;                     break ;                 }             }             if  (hasPassed == n)                 return  i;         }         return  1 ;     } } 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 class  Solution  {    public  boolean  robot (String cmd, int [][] obstacles, int  x, int  y)  {         int  n  =  cmd.length();         int  sx  =  0 , sy = 0 ;                  for  (int  i  =  0 ; i < n; ++ i) {             char  c  =  cmd.charAt(i);             if  (c == 'U' ) ++ sy;             else  ++ sx;         }                           boolean  canFinish  =  canReach(cmd, x, y, sx, sy);         if  (!canFinish) return  false ;                           for  (int [] o : obstacles) {             if  (o[0 ] > x || o[1 ] > y)                 continue ;             if  (canReach(cmd, o[0 ], o[1 ], sx, sy)) return  false ;         }         return  true ;     }          public  boolean  canReach (String cmd, int  tx, int  ty, int  x, int  y)  {                  int  round  =  Math.min(tx/x, ty/y);         int  nx  =  round*x, ny = round*y;         if  (nx == tx && ny == ty) return  true ;         int  n  =  cmd.length();         for  (int  i  =  0 ; i < n; ++ i) {             char  c  =  cmd.charAt(i);             if  (c == 'U' ) ++ ny;             else  ++ nx;             if  (nx > tx || ny > ty) return  false ;             if  (nx == tx && ny == ty) return  true ;         }         return  true ;     } } 
 
Leetcode 135.分发糖果 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class  Solution  {    public  int  candy (int [] ratings)  {         int  n  =  ratings.length;         int  ret  =  1 ;         int  inc  =  1 , dec = 0 , pre = 1 ;         for  (int  i  =  1 ; i < n; i++) {             if  (ratings[i] >= ratings[i - 1 ]) {                 dec = 0 ;                 pre = ratings[i] == ratings[i - 1 ] ? 1  : pre + 1 ;                 ret += pre;                 inc = pre;             } else  {                 dec++;                 if  (dec == inc) {                     dec++;                 }                 ret += dec;                 pre = 1 ;             }         }         return  ret;     } } 
 
Leetcode 42.接雨水 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 class  Solution  {    public  int  trap (int [] height)  {         int  length  =  height.length;         int  ans  =  0 ;         for  (int  i  = 1 ;i<length-1 ;i++){             int  max_left  =  0 ;             for  (int  j  =  i-1 ;j>=0 ;j--){                 if  (height[j]>max_left)                 max_left = height[j];             }             int  max_right  =  0 ;             for  (int  j  =  i+1 ;j<length;j++){                 if  (height[j]>max_right)                 max_right = height[j];             }             if  (height[i]<Math.min(max_left,max_right)){                 ans+=Math.min(max_left,max_right)- height[i];             }         }         return  ans;     } } 
 
Leetcode 13.罗马数字转整形 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class  Solution  {    public  int  romanToInt (String s)  {         HashMap<Character,Integer> romanMap = new  HashMap ();         romanMap.put('I' ,1 );         romanMap.put('V' ,5 );         romanMap.put('X' ,10 );         romanMap.put('L' ,50 );         romanMap.put('C' ,100 );         romanMap.put('D' ,500 );         romanMap.put('M' ,1000 );         int  length  =  s.length();         int  ans  =  0 ;         for  (int  i  =  0 ;i<length;i++){             if  (i==length-1 )ans+=romanMap.get(s.charAt(i));             else {                 if  (romanMap.get(s.charAt(i))<romanMap.get(s.charAt(i+1 ))){                     ans-=romanMap.get(s.charAt(i));                 }else {                     ans+=romanMap.get(s.charAt(i));                 }             }                      }         return  ans;     } } 
 
Leetcode 12.整数转罗马数字 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class  Solution  {    int [] values = {1000 , 900 , 500 , 400 , 100 , 90 , 50 , 40 , 10 , 9 , 5 , 4 , 1 };     String[] symbols = {"M" , "CM" , "D" , "CD" , "C" , "XC" , "L" , "XL" , "X" , "IX" , "V" , "IV" , "I" };     public  String intToRoman (int  num)  {         StringBuffer  roman  =  new  StringBuffer ();         for  (int  i  =  0 ; i < values.length; ++i) {             int  value  =  values[i];             String  symbol  =  symbols[i];             while  (num >= value) {                 num -= value;                 roman.append(symbol);             }             if  (num == 0 ) {                 break ;             }         }         return  roman.toString();     } } 
 
Leetcode 63.不同路径2 
动态规划
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 class  Solution  {    public  int  uniquePathsWithObstacles (int [][] obstacleGrid)  {         if  (obstacleGrid == null  || obstacleGrid.length == 0  || obstacleGrid[0 ].length == 0 ) return  0 ;         int  m  =  obstacleGrid.length;         int  n  =  obstacleGrid[0 ].length;                  int [][] dp = new  int [m][n];                  for  (int  j  =  0 ; j < n; j++) {             if  (obstacleGrid[0 ][j] == 1 ) break ;              dp[0 ][j] = 1 ;         }                  for  (int  i  =  0 ; i < m; i++) {             if  (obstacleGrid[i][0 ] == 1 ) break ;              dp[i][0 ] = 1 ;         }                  for  (int  i  =  1 ; i < m; i++) {             for  (int  j  =  1 ; j < n; j++) {                 if  (obstacleGrid[i][j] == 0 ) {                     dp[i][j] = dp[i - 1 ][j] + dp[i][j - 1 ];                 } else  {                     dp[i][j] = 0 ;                  }             }         }         return  dp[m - 1 ][n - 1 ];      } } 
 
Leetcode 68.文本左右对齐 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 class  Solution  {    public  List<String> fullJustify (String[] words, int  maxWidth)  {         List<String> ans = new  ArrayList <String>();         int  right  =  0 , n = words.length;         while  (true ) {             int  left  =  right;              int  sumLen  =  0 ;                           while  (right < n && sumLen + words[right].length() + right - left <= maxWidth) {                 sumLen += words[right++].length();             }                          if  (right == n) {                 StringBuffer  sb  =  join(words, left, n, " " );                 sb.append(blank(maxWidth - sb.length()));                 ans.add(sb.toString());                 return  ans;             }             int  numWords  =  right - left;             int  numSpaces  =  maxWidth - sumLen;                          if  (numWords == 1 ) {                 StringBuffer  sb  =  new  StringBuffer (words[left]);                 sb.append(blank(numSpaces));                 ans.add(sb.toString());                 continue ;             }                          int  avgSpaces  =  numSpaces / (numWords - 1 );             int  extraSpaces  =  numSpaces % (numWords - 1 );             StringBuffer  sb  =  new  StringBuffer ();             sb.append(join(words, left, left + extraSpaces + 1 , blank(avgSpaces + 1 )));              sb.append(blank(avgSpaces));             sb.append(join(words, left + extraSpaces + 1 , right, blank(avgSpaces)));              ans.add(sb.toString());         }     }          public  String blank (int  n)  {         StringBuffer  sb  =  new  StringBuffer ();         for  (int  i  =  0 ; i < n; ++i) {             sb.append(' ' );         }         return  sb.toString();     }          public  StringBuffer join (String[] words, int  left, int  right, String sep)  {         StringBuffer  sb  =  new  StringBuffer (words[left]);         for  (int  i  =  left + 1 ; i < right; ++i) {             sb.append(sep);             sb.append(words[i]);         }         return  sb;     } } 
 
Leetcode 125.验证回文串 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 class  Solution  {    public  boolean  isPalindrome (String s)  {         String  s2  =  s.toLowerCase();         Stack  stack  =  new  Stack ();         Queue  queue  =  new  LinkedList ();         int  length  =  s2.length();         for  (int  i=0 ;i<length;i++){             if  (Character.isLetter(s2.charAt(i))||Character.isDigit(s2.charAt(i))){                 stack.push(s2.charAt(i));                 queue.offer(s2.charAt(i));             }         }         boolean  ans  =  true ;         while  (!stack.isEmpty()){             if  (stack.peek()==queue.peek()){                 stack.pop();                 queue.poll();             }else {                 ans = false ;                 break ;             }         }         return  ans;     } } 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 class  Solution  {    public  int [] twoSum(int [] numbers, int  target) {         int  low  =  0 , high = numbers.length - 1 ;         while  (low < high) {             int  sum  =  numbers[low] + numbers[high];             if  (sum == target) {                 return  new  int []{low + 1 , high + 1 };             } else  if  (sum < target) {                 ++low;             } else  {                 --high;             }         }         return  new  int []{-1 , -1 };     } } 
 
Leetcode 11.盛最多水的容器 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 class  Solution  {    public  int  maxArea (int [] height)  {         int  length  =  height.length;         int  ans  =  -1 ;         for  (int  i  = 0 ;i<length-1 ;i++){             for  (int  j=i+1 ;j<length;j++){                 if  ((j-i)*Math.min(height[i],height[j])>ans){                     ans = (j-i)*Math.min(height[i],height[j]);                 }             }         }         return  ans;     } } class  Solution  {    public  int  maxArea (int [] height)  {         int  length  =  height.length;         int  ans  =  0 ;         int  start  =  0 ;         int  end  =  length-1 ;         while (start<end){             int  minHeight  =  Math.min(height[start],height[end]);             if  ((end-start)*minHeight>ans){                 ans = (end-start)*minHeight;             }             if  (minHeight==height[start])start++;             else  end--;         }         return  ans;     } } 
 
Leetcode 15.三数之和 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 class  Solution  {    public  List<List<Integer>> threeSum (int [] nums)  {         Arrays.sort(nums);         int  n  =  nums.length;         List<List<Integer>>ans = new  ArrayList <List<Integer>>();         for  (int  i  = 0 ;i<n;i++){             if  (i>0 &&nums[i]==nums[i-1 ]){                 continue ;             }             int  k  =  n-1 ;             int  t  =  -nums[i];             for  (int  j  =  i+1 ;j<n;j++){                 if  (j>i+1 &&nums[j]==nums[j-1 ]){                     continue ;                 }                 while  (j<k&&nums[j]+nums[k]>t){                     k--;                 }                 if  (j==k)break ;                 if  (nums[j]+nums[k]==t){                     List<Integer>list = new  ArrayList <Integer>();                     list.add(nums[i]);                     list.add(nums[j]);                     list.add(nums[k]);                     ans.add(list);                 }             }         }         return  ans;     } } 
 
Leetcode 209.长度最小的子数组 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 class  Solution  {    public  int  minSubArrayLen (int  target, int [] nums)  {         int  length  =  nums.length;         int  presum[]=new  int [length+1 ];         int  ans  =  100000 ;         for  (int  i=1 ;i<=length;i++){                 presum[i]=presum[i-1 ]+nums[i-1 ];         }         if  (presum[length]<target)return  0 ;         for  (int  i=0 ;i<length;i++){             for  (int  j=length;j>=i;j--){                     if  (presum[j]-presum[i]>=target){                         if  (j-i<ans)ans = j-i;                     }             }         }         return  ans;     } } class  Solution  {    public  int  minSubArrayLen (int  target, int [] nums)  {         int  length  =  nums.length;         int  sum  =  0 ;         int  start  =  0 ;         int  end  =  0 ;         int  ans  =  100000 ;         boolean  flag  = false ;         for  (int  i=0 ;i<length;i++){             sum+=nums[i];             end++;             if  (sum>=target){                 while  (sum>=target){                     if  (end-start<ans)ans = end -start;                     flag = true ;                     sum-=nums[start];                     start++;                 }              }         }         if  (!flag)return  0 ;         return  ans; } } 
 
Leetcode 3.无重复字符的最长子串 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class  Solution  {    public  int  lengthOfLongestSubstring (String s)  {         HashMap<Character,Integer> map= new  HashMap ();         int  start  =  0 ;         int  ans  =  0 ;         for  (int  i  =  0 ;i<s.length();i++){             if  (map.get(Character.valueOf(s.charAt(i)))!=null &&start<map.get(Character.valueOf(s.charAt(i)))+1 ){                  start=map.get(Character.valueOf(s.charAt(i)))+1 ;              }             map.put(Character.valueOf(s.charAt(i)),i);             if  (i-start+1 >ans)ans = i-start+1 ;         }         return  ans;     } } 
 
Leetcode 36.有效的数独 
暴力解法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 class  Solution  {    public  boolean  isValidSudoku (char [][] board)  {         for (int  i  =  0 ; i < board.length; i++){             for (int  j  =  0 ; j < board[0 ].length; j++){                 if (board[i][j] >= '0'  && board[i][j] <= '9' ){                     if (!getEffective(i, j, board)){                         return  false ;                     }                 }             }         }         return  true ;     }     public  boolean  getEffective (int  i, int  j, char [][] board) {                  for (int  k  =  0 ; k < board[i].length; k++){             if (board[i][k] == board[i][j] && k != j){                 return  false ;             }         }                  for (int  k  =  0 ; k < board.length; k++){             if (board[k][j] == board[i][j] && k != i){                 return  false ;             }         }                  int  heng  =  (i / 3 ) * 3 ;         int  zhong  =  (j / 3 ) * 3 ;         for (int  k1  =  heng; k1 < heng + 3 ; k1++){             for (int  k2  =  zhong; k2 < zhong + 3 ; k2++){                 if ((board[k1][k2] == board[i][j]) && (k1 != i && k2 != j)){                     return  false ;                 }             }         }         return  true ;     } } 
 
Leetcode 54.螺旋矩阵 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class  Solution  {    public  List<Integer> spiralOrder (int [][] matrix)  {         List<Integer> order = new  ArrayList <Integer>();         if  (matrix == null  || matrix.length == 0  || matrix[0 ].length == 0 ) {             return  order;         }         int  rows  =  matrix.length, columns = matrix[0 ].length;         boolean [][] visited = new  boolean [rows][columns];         int  total  =  rows * columns;         int  row  =  0 , column = 0 ;         int [][] directions = {{0 , 1 }, {1 , 0 }, {0 , -1 }, {-1 , 0 }};         int  directionIndex  =  0 ;         for  (int  i  =  0 ; i < total; i++) {             order.add(matrix[row][column]);             visited[row][column] = true ;             int  nextRow  =  row + directions[directionIndex][0 ], nextColumn = column + directions[directionIndex][1 ];             if  (nextRow < 0  || nextRow >= rows || nextColumn < 0  || nextColumn >= columns || visited[nextRow][nextColumn]) {                 directionIndex = (directionIndex + 1 ) % 4 ;             }             row += directions[directionIndex][0 ];             column += directions[directionIndex][1 ];         }         return  order;     } } 
 
Leetcode 48.旋转图像 
这种旋转的题就注意位置映射关系就好
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class  Solution  {    public  void  rotate (int [][] matrix)  {         int  n  =  matrix.length;         for  (int  i  =  0 ; i < n / 2 ; ++i) {             for  (int  j  =  0 ; j < (n + 1 ) / 2 ; ++j) {                 int  temp  =  matrix[i][j];                 matrix[i][j] = matrix[n - j - 1 ][i];                 matrix[n - j - 1 ][i] = matrix[n - i - 1 ][n - j - 1 ];                 matrix[n - i - 1 ][n - j - 1 ] = matrix[j][n - i - 1 ];                 matrix[j][n - i - 1 ] = temp;             }         }     } } 
 
Leetcode 289.生命游戏 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 class  Solution  {    public  void  gameOfLife (int [][] board)  {         int  m  =  board.length;         int  n  =  board[0 ].length;         boolean  isAlive[][]=new  boolean [m][n];         for  (int  i  = 0 ;i<m;i++){             for  (int  j  = 0 ;j<n;j++){                 int  num  =  getNum(board,i,j,m,n);                 if  (board[i][j]==1 ){                     if  (num<2 ||num>3 )isAlive[i][j]=false ;                     if  (num==2 ||num==3 )isAlive[i][j]=true ;                 }else {                     if  (num==3 )isAlive[i][j]=true ;                 }             }         }         for  (int  i=0 ;i<m;i++){             for  (int  j  = 0 ;j<n;j++){                 if  (isAlive[i][j])board[i][j]=1 ;                 else {                     board[i][j]=0 ;                 }             }         }     }     public  int  getNum (int [][] board,int  x,int  y,int  m, int  n) {         int  num  =  0 ;         for  (int  i=x-1 ;i<=x+1 ;i++){             if  (i<0 ||i>=m)continue ;             for  (int  j= y-1 ;j<=y+1 ;j++){                 if  (j<0 ||j>=n||i==x&&j==y)continue ;                 if  (board[i][j]==1 )num++;             }         }         return  num;     } } 
 
哈希表 
Leetcode 383.赎金信 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class  Solution  {    public  boolean  canConstruct (String ransomNote, String magazine)  {         int  nums[]=new  int [26 ];         int  size  =  magazine.length();         for  (int  i=0 ;i<size;i++){             nums[magazine.charAt(i)-'a' ]+=1 ;         }         int  rSize= ransomNote.length();         for  (int  i  = 0 ;i<rSize;i++){             if  (nums[ransomNote.charAt(i)-'a' ]<=0 )return  false ;             nums[ransomNote.charAt(i)-'a' ]-=1 ;         }         return  true ;     } } 
 
Leetcode 205.同构字符串 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 class  Solution  {    public  boolean  isIsomorphic (String s, String t)  {         Map<Character,Character> cMap = new  HashMap <Character,Character>();         Map<Character,Character> cMap2 = new  HashMap <Character,Character>();         int  length  =  s.length();         for  (int  i  =  0 ;i<length;i++){             if  (cMap.containsKey(Character.valueOf(s.charAt(i)))||cMap2.containsKey(Character.valueOf(t.charAt(i)))){                 if  (cMap.get(Character.valueOf(s.charAt(i)))!=Character.valueOf(t.charAt(i)))                 return  false ;             }else {                 cMap.put(Character.valueOf(s.charAt(i)),Character.valueOf(t.charAt(i)));                 cMap2.put(Character.valueOf(t.charAt(i)),Character.valueOf(s.charAt(i)));             }         }         return  true ;     } } 
 
Leetcode 290.单词规律 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 class  Solution  {    public  boolean  wordPattern (String pattern, String s)  {         Map<Character,String> cMap = new  HashMap <Character,String>();                  Map<String,Character> cMap2 = new  HashMap <String,Character>();         int  length  =  pattern.length();         String words[]=s.split(" " );         if  (words.length!=length)return  false ;         for  (int  i  =  0 ;i<length;i++){             if  (cMap.containsKey(Character.valueOf(pattern.charAt(i)))){                 if  (!cMap.get(Character.valueOf(pattern.charAt(i))).equals(words[i])){                 return  false ;}             }             else  if  (cMap2.containsKey(words[i])){                 return  false ;             }                          else {                 cMap.put(Character.valueOf(pattern.charAt(i)),words[i]);                 cMap2.put(words[i],Character.valueOf(pattern.charAt(i)));             }         }         return  true ;     } } 
 
Leetcode 49.字母异位词分组 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 class  Solution  {    public  List<List<String>> groupAnagrams (String[] strs)  {         HashMap<HashSet<Character>,ArrayList<String>> map = new  HashMap ();         int  length  =  strs.length;         for  (int  i  =  0 ; i<length; i++){             int  length2=strs[i].length();             HashSet<Character>set = new  HashSet ();             for  (int  j  =  0  ;j<length2;j++){                 set.add(Character.valueOf(strs[i].charAt(j)));             }             if  (!map.containsKey(set)){                 ArrayList<String>list = new  ArrayList ();                 list.add(strs[i]);                 map.put(set,list);             }else {                 map.get(set).add(strs[i]);             }         }         List<List<String>> ans = new  ArrayList <List<String>>();         for  (HashSet<Character> key: map.keySet()){             ans.add(map.get(key));         }         return  ans;     } } 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 class  Solution  {    public  List<List<String>> groupAnagrams (String[] strs)  {        Map<String,List<String>>map = new  HashMap ();         int  length  =  strs.length;         for  (int  i  =  0 ; i<length; i++){             int  length2=strs[i].length();             char  word[]=new  char [length2];             for  (int  j  =  0 ;j<length2;j++){                 word[j]=strs[i].charAt(j) ;             }             Arrays.sort(word);             String  key  =  new  String (word);             if  (!map.containsKey(key)){                 List<String> list = new  ArrayList ();                 list.add(strs[i]);                 map.put(key,list);             }else {                 map.get(key).add(strs[i]);             }               }         List<List<String>> ans = new  ArrayList <List<String>>();         for  (String key: map.keySet()){             ans.add(map.get(key));         }         return  ans;     } } 
 
Leetcode 128.最长连续序列 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class  Solution  {    public  int  longestConsecutive (int [] nums)  {         Arrays.sort(nums);         int  length  =  nums.length;         if  (length==0 ||length==1 )return  length;         int  num  =  1 ;         int  ans  =  1 ;         for  (int  i  =  1 ;i<length;i++){             if  (nums[i-1 ]+1 ==nums[i]){                 num++;                 ans=Math.max(num,ans);             }else  if (nums[i-1 ]==nums[i]){                 continue ;             }else {                 num=1 ;             }               }         return  ans;     } } 
 
Leetcode 76.最小覆盖子串 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 class  Solution  {    Map<Character, Integer> ori = new  HashMap <Character, Integer>();     Map<Character, Integer> cnt = new  HashMap <Character, Integer>();     public  String minWindow (String s, String t)  {         int  tLen  =  t.length();         for  (int  i  =  0 ; i < tLen; i++) {             char  c  =  t.charAt(i);             ori.put(c, ori.getOrDefault(c, 0 ) + 1 );         }         int  l  =  0 , r = -1 ;         int  len  =  Integer.MAX_VALUE, ansL = -1 , ansR = -1 ;         int  sLen  =  s.length();         while  (r < sLen) {             ++r;             if  (r < sLen && ori.containsKey(s.charAt(r))) {                 cnt.put(s.charAt(r), cnt.getOrDefault(s.charAt(r), 0 ) + 1 );             }             while  (check() && l <= r) {                 if  (r - l + 1  < len) {                     len = r - l + 1 ;                     ansL = l;                     ansR = l + len;                 }                 if  (ori.containsKey(s.charAt(l))) {                     cnt.put(s.charAt(l), cnt.getOrDefault(s.charAt(l), 0 ) - 1 );                 }                 ++l;             }         }         return  ansL == -1  ? ""  : s.substring(ansL, ansR);     }     public  boolean  check ()  {         Iterator  iter  =  ori.entrySet().iterator();          while  (iter.hasNext()) {              Map.Entry  entry  =  (Map.Entry) iter.next();              Character  key  =  (Character) entry.getKey();              Integer  val  =  (Integer) entry.getValue();              if  (cnt.getOrDefault(key, 0 ) < val) {                 return  false ;             }         }          return  true ;     } } 
 
区间 
Leetcode 228.汇总区间 
注意Integer.toString()和StringBuilder的用法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class  Solution  {    public  List<String> summaryRanges (int [] nums)  {         List<String> ret = new  ArrayList <String>();         int  i  =  0 ;         int  n  =  nums.length;         while  (i < n) {             int  low  =  i;             i++;             while  (i < n && nums[i] == nums[i - 1 ] + 1 ) {                 i++;             }             int  high  =  i - 1 ;             StringBuffer  temp  =  new  StringBuffer (Integer.toString(nums[low]));             if  (low < high) {                 temp.append("->" );                 temp.append(Integer.toString(nums[high]));             }             ret.add(temp.toString());         }         return  ret;     } } 
 
Leetcode 56.合并区间 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class  Solution  {    public  int [][] merge(int [][] intervals) {         if  (intervals.length == 0 ) {             return  new  int [0 ][2 ];         }         Arrays.sort(intervals, new  Comparator <int []>() {             public  int  compare (int [] interval1, int [] interval2)  {                 return  interval1[0 ] - interval2[0 ];             }         });         List<int []> merged = new  ArrayList <int []>();         for  (int  i  =  0 ; i < intervals.length; ++i) {             int  L  =  intervals[i][0 ], R = intervals[i][1 ];             if  (merged.size() == 0  || merged.get(merged.size() - 1 )[1 ] < L) {                 merged.add(new  int []{L, R});             } else  {                 merged.get(merged.size() - 1 )[1 ] = Math.max(merged.get(merged.size() - 1 )[1 ], R);             }         }         return  merged.toArray(new  int [merged.size()][]);      } } 
 
Leetcode 57.插入区间 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 class  Solution  {    public  int [][] insert(int [][] intervals, int [] newInterval) {         int  length1  =  intervals.length;         int  length2  =  length1+1 ;         int  [][]ans = new  int [length2][2 ];         for  (int  i  =  0 ;i<length1;i++){             ans[i][0 ]=intervals[i][0 ];             ans[i][1 ]=intervals[i][1 ];         }         ans[length1][0 ]=newInterval[0 ];         ans[length1][1 ]=newInterval[1 ];         Arrays.sort(ans,new  Comparator <int []>(){             public  int  compare (int []nums1,int [] nums2) {                 return  nums1[0 ]-nums2[0 ];             }         });         List<int []>ans2 = new  ArrayList <int []>();         for  (int  i=0 ;i<length2;i++){             if  (ans2.size()==0 ||ans2.get(ans2.size()-1 )[1 ]<ans[i][0 ]){                 ans2.add(new  int []{ans[i][0 ],ans[i][1 ]});             }else {                 ans2.get(ans2.size()-1 )[1 ]=Math.max(ans[i][1 ],ans2.get(ans2.size()-1 )[1 ]);             }         }         return  ans2.toArray(new  int [ans2.size()][]);     } } 
 
Leetcode 452.用最少数量的箭引爆气球 
注意贪心
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class  Solution  {    public  int  findMinArrowShots (int [][] points)  {         int  length  =  points.length;         Arrays.sort(points,(a,b)->Integer.compare(a[1 ],b[1 ]));         List<int []> ans = new  ArrayList ();         for  (int  i  = 0 ;i<length;i++){             if  (ans.size()==0 ||ans.get(ans.size()-1 )[1 ]<points[i][0 ]){                 ans.add(new  int []{points[i][0 ],points[i][1 ]});             }else {                continue ;             }         }         return  ans.size();     } } 
 
栈 
Leetcode 71.简化路径 
注意双端队列Deque用LinkedList来实现,StringBuilder.tostring()转为字符串。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 class  Solution  {    public  String simplifyPath (String path)  {         String []strs = path.split("/" );         Deque<String>stack = new  LinkedList ();         for  (String str:strs){             if  (".." .equals(str)){                 if  (!stack.isEmpty()){                     stack.pollLast();                 }             }else  if  (str.length()>0 &&!"." .equals(str)){                 stack.offerLast(str);             }         }         StringBuilder  sb  =  new  StringBuilder ();         if  (stack.isEmpty()){             sb.append("/" );         }else {             while  (!stack.isEmpty()){                 sb.append("/" );                 sb.append(stack.pollFirst());             }         }         return  sb.toString();     } } 
 
Leetcode 155.最小栈 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class  MinStack  {    ArrayList<Integer> stack;     public  MinStack ()  {         this . stack =  new  ArrayList ();     }          public  void  push (int  val)  {         stack.add(val);     }          public  void  pop ()  {         stack.remove(stack.size()-1 );     }          public  int  top ()  {         return  stack.get(stack.size()-1 ).intValue();     }          public  int  getMin ()  {           int  ans  =  Integer.MAX_VALUE;         for  (Integer num:stack){             if  (num<ans)ans = num;         }         return  ans;     } } 
 
Leetcode 150.逆波兰表达式 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class  Solution  {    public  int  evalRPN (String[] tokens)  {         Stack<String>stack = new  Stack ();         for  (String str:tokens){             if  (!"+" .equals(str)&&!"-" .equals(str)&&!"*" .equals(str)&&!"/" .equals(str)){                 stack.push(str);             }else  {                 int  b  =  Integer.parseInt(stack.pop());                 int  a  =  Integer.parseInt(stack.pop());                 if  ("+" .equals(str)){                     stack.push(String.valueOf(a+b));                 }else  if  ("-" .equals(str)){                     stack.push(String.valueOf(a-b));                 }else  if  ("*" .equals(str)){                     stack.push(String.valueOf(a*b));                 }else  if  ("/" .equals(str)){                     stack.push(String.valueOf(a/b));                 }             }         }         return  Integer.parseInt(stack.pop());     } } 
 
链表 
注意哑结点的构造,很方便!!!
Leetcode 21.合并两个有序链表 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 class  Solution  {    public  ListNode mergeTwoLists (ListNode l1, ListNode l2)  {         ListNode  prehead  =  new  ListNode (-1 );         ListNode  prev  =  prehead;         while  (l1 != null  && l2 != null ) {             if  (l1.val <= l2.val) {                 prev.next = l1;                 l1 = l1.next;             } else  {                 prev.next = l2;                 l2 = l2.next;             }             prev = prev.next;         }                  prev.next = l1 == null  ? l2 : l1;         return  prehead.next;     } } 
 
Leetcode 141.环形链表 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 public  class  Solution  {    public  boolean  hasCycle (ListNode head)  {         ListNode  slow  = head;         ListNode  fast  =  head;         while (fast!=null &&slow!=null ){             slow=slow.next;             fast = fast.next;             if  (fast==null )return  false ;             fast = fast.next;             if  (fast == slow)return  true ;         }         return  false ;     } } 
 
Leetcode 2.两数相加 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 class  Solution  {    public  ListNode addTwoNumbers (ListNode l1, ListNode l2)  {         ListNode  head  =  null , tail = null ;         int  carry  =  0 ;         while  (l1 != null  || l2 != null ) {             int  n1  =  l1 != null  ? l1.val : 0 ;             int  n2  =  l2 != null  ? l2.val : 0 ;             int  sum  =  n1 + n2 + carry;             if  (head == null ) {                 head = tail = new  ListNode (sum % 10 );             } else  {                 tail.next = new  ListNode (sum % 10 );                 tail = tail.next;             }             carry = sum / 10 ;             if  (l1 != null ) {                 l1 = l1.next;             }             if  (l2 != null ) {                 l2 = l2.next;             }         }         if  (carry > 0 ) {             tail.next = new  ListNode (carry);         }         return  head;     } } 
 
Leetcode 206.反转链表 
递归做法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class  Solution  {    public  ListNode reverseList (ListNode head)  {         if  (head==null ||head.next==null )return  head;         ListNode  newHead  =  reverseList(head.next);         head.next.next = head;         head.next=null ;         return  newHead;     } } 
 
Leetcode 92.反转链表2 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 class  Solution  {    public  ListNode reverseBetween (ListNode head, int  left, int  right)  {                  ListNode  dummyNode  =  new  ListNode (-1 );         dummyNode.next = head;         ListNode  pre  =  dummyNode;                           for  (int  i  =  0 ; i < left - 1 ; i++) {             pre = pre.next;         }                  ListNode  rightNode  =  pre;         for  (int  i  =  0 ; i < right - left + 1 ; i++) {             rightNode = rightNode.next;         }                  ListNode  leftNode  =  pre.next;         ListNode  curr  =  rightNode.next;                  pre.next = null ;         rightNode.next = null ;                  reverseLinkedList(leftNode);                  pre.next = rightNode;         leftNode.next = curr;         return  dummyNode.next;     }     private  void  reverseLinkedList (ListNode head)  {                  ListNode  pre  =  null ;         ListNode  cur  =  head;         while  (cur != null ) {             ListNode  next  =  cur.next;             cur.next = pre;             pre = cur;             cur = next;         }     } } 
 
Leetcode 138.随机链表的复制 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 class  Solution  {    Map<Node,Node>map = new  HashMap ();     public  Node copyRandomList (Node head)  {         if  (head == null )return  null ;         if  (!map.containsKey(head)){             Node  newNode  =  new  Node (head.val);             map.put(head,newNode);             newNode.next = copyRandomList(head.next);             newNode.random = copyRandomList(head.random);         }         return  map.get(head);     } } 
 
Leetcode 19.删除链表的倒数第N个节点 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 class  Solution  {    public  ListNode removeNthFromEnd (ListNode head, int  n)  {                  ListNode  currentNode  =  head;         ArrayList<ListNode> nodes = new  ArrayList ();          while (currentNode!=null ){             nodes.add(currentNode);             currentNode = currentNode.next;         }         int  num  =  nodes.size();         if  (num == 1 )return  null ;         ListNode  pre  =  new  ListNode (-1 ,head);         currentNode = pre;         for  (int  i=1 ;i<num-n+1 ;i++){             currentNode = currentNode.next;         }         currentNode.next=currentNode.next.next;         return  pre.next;     } } 
 
Leetcode 82.删除排序链表中的重复元素2 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class  Solution  {    public  ListNode deleteDuplicates (ListNode head)  {         if  (head == null ) {             return  head;         }                  ListNode  dummy  =  new  ListNode (0 , head);         ListNode  cur  =  dummy;         while  (cur.next != null  && cur.next.next != null ) {             if  (cur.next.val == cur.next.next.val) {                 int  x  =  cur.next.val;                 while  (cur.next != null  && cur.next.val == x) {                     cur.next = cur.next.next;                 }             } else  {                 cur = cur.next;             }         }         return  dummy.next;     } } 
 
Leetcode 61.旋转链表 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 class  Solution  {    public  ListNode rotateRight (ListNode head, int  k)  {         ArrayList<ListNode> nodes = new  ArrayList ();         ListNode  dumbNode  =  new  ListNode (-111 ,head);         ListNode  cur  =  head;         while (cur!=null ){             nodes.add(cur);             cur=cur.next;         }         int  num  =  nodes.size();         if  (num==0 )return  head;         k = k%num;         if  (k==0 )return  head;         int  preOrder  =  num-k-1 ;         cur = dumbNode;         for  (int  i  =  0 ;i<=preOrder;i++){             cur = cur.next;         }         ListNode  preNode  =  cur;         ListNode  next  = preNode.next;         ListNode  last  =  next;         while (last!=null ){             if  (last.next==null )break ;             last = last.next;         }         dumbNode.next = next;         last.next = head;         preNode.next = null ;         return  dumbNode.next;     } } 
 
Leetcode 146.LRU缓存 
直接继承LinkedHashMap
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class  LRUCache  extends  LinkedHashMap <Integer, Integer>{    private  int  capacity;          public  LRUCache (int  capacity)  {         super (capacity, 0.75F , true );         this .capacity = capacity;     }     public  int  get (int  key)  {         return  super .getOrDefault(key, -1 );     }     public  void  put (int  key, int  value)  {         super .put(key, value);     }     @Override      protected  boolean  removeEldestEntry (Map.Entry<Integer, Integer> eldest)  {         return  size() > capacity;      } } 
 
哈希+双链表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 public  class  LRUCache  {    class  DLinkedNode  {         int  key;         int  value;         DLinkedNode prev;         DLinkedNode next;         public  DLinkedNode ()  {}         public  DLinkedNode (int  _key, int  _value)  {key = _key; value = _value;}     }     private  Map<Integer, DLinkedNode> cache = new  HashMap <Integer, DLinkedNode>();     private  int  size;     private  int  capacity;     private  DLinkedNode head, tail;     public  LRUCache (int  capacity)  {         this .size = 0 ;         this .capacity = capacity;                  head = new  DLinkedNode ();         tail = new  DLinkedNode ();         head.next = tail;         tail.prev = head;     }     public  int  get (int  key)  {         DLinkedNode  node  =  cache.get(key);         if  (node == null ) {             return  -1 ;         }                  moveToHead(node);         return  node.value;     }     public  void  put (int  key, int  value)  {         DLinkedNode  node  =  cache.get(key);         if  (node == null ) {                          DLinkedNode  newNode  =  new  DLinkedNode (key, value);                          cache.put(key, newNode);                          addToHead(newNode);             ++size;             if  (size > capacity) {                                  DLinkedNode  tail  =  removeTail();                                  cache.remove(tail.key);                 --size;             }         }         else  {                          node.value = value;             moveToHead(node);         }     }     private  void  addToHead (DLinkedNode node)  {         node.prev = head;         node.next = head.next;         head.next.prev = node;         head.next = node;     }     private  void  removeNode (DLinkedNode node)  {         node.prev.next = node.next;         node.next.prev = node.prev;     }     private  void  moveToHead (DLinkedNode node)  {         removeNode(node);         addToHead(node);     }     private  DLinkedNode removeTail ()  {         DLinkedNode  res  =  tail.prev;         removeNode(res);         return  res;     } } 
 
二分查找 
Leetcode 35.搜索插入位置 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 class  Solution  {    public  int  searchInsert (int [] nums, int  target)  {         int  start  =  0 ;         int  end  =  nums.length-1 ;         int  ans=nums.length;         if  (nums[0 ]>=target)return  0 ;         while (start<=end){             int  mid  =  (end-start)/2 +start;             if  (nums[mid]>=target){                 end =mid-1 ;                 ans =mid;             }else {                 start =mid+1 ;             }         }         return  ans;     } } 
 
Leetcode 74.搜索二维矩阵 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class  Solution  {    public  boolean  searchMatrix (int [][] matrix, int  target)  {         int  m  =  matrix.length;         int  n  =  matrix[0 ].length;         for  (int  i=0 ;i<m;i++){             if  (target>matrix[i][n-1 ])continue ;             for  (int  j=0 ;j<n;j++){                 if  (matrix[i][j]==target)return  true ;             }             return  false ;         }         return  false ;     }  } 
 
Leetcode 200.岛屿数量 
常规的dfs,甚至不用回溯
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 class  Solution  {    void  dfs (char [][] grid, int  r, int  c)  {         int  nr  =  grid.length;         int  nc  =  grid[0 ].length;         if  (r < 0  || c < 0  || r >= nr || c >= nc || grid[r][c] == '0' ) {             return ;         }         grid[r][c] = '0' ;         dfs(grid, r - 1 , c);         dfs(grid, r + 1 , c);         dfs(grid, r, c - 1 );         dfs(grid, r, c + 1 );     }     public  int  numIslands (char [][] grid)  {         if  (grid == null  || grid.length == 0 ) {             return  0 ;         }         int  nr  =  grid.length;         int  nc  =  grid[0 ].length;         int  num_islands  =  0 ;         for  (int  r  =  0 ; r < nr; ++r) {             for  (int  c  =  0 ; c < nc; ++c) {                 if  (grid[r][c] == '1' ) {                     ++num_islands;                     dfs(grid, r, c);                 }             }         }         return  num_islands;     } } 
 
Leetcode 130.被围绕的区域 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 class  Solution  {    public  void  solve (char [][] board)  {         int  m  =  board.length;         int  n  =  board[0 ].length;         for  (int  i=0 ;i<m;i++){             dfs(board,i,0 );             dfs(board,i,n-1 );         }         for  (int  i=0 ;i<n;i++){             dfs(board,0 ,i);             dfs(board,m-1 ,i);         }         for  (int  i=0 ;i<m;i++){             for (int  j=0 ;j<n;j++){                 if  (board[i][j]=='V' )board[i][j]='O' ;                   else  if (board[i][j]=='O' ){                     board[i][j]='X' ;                 }               }         }     }     public  void  dfs (char [][]board,int  x, int  y) {         if  (x<0 ||y<0 ||x>=board.length||y>=board[0 ].length||board[x][y]!='O' )return ;         board[x][y]='V' ;         dfs(board,x+1 ,y);         dfs(board,x,y+1 );         dfs(board,x-1 ,y);         dfs(board,x,y-1 );     } } 
 
Leetcode 2576.求出最多标记下标 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class  Solution  {public :    int  maxNumOfMarkedIndices (vector<int >& nums)  {         sort(nums.begin(), nums.end());         int  n  =  nums.size();         int  m  =  n / 2 ;         int  res  =  0 ;         for  (int  i  =  0 , j = m; i < m && j < n; i++) {             while  (j < n && 2  * nums[i] > nums[j]) {                 j++;             }             if  (j < n) {                 res += 2 ;                 j++;             }         }         return  res;     } }; 
 
Leetcode 300.最长递增子序列 
会用到二分查找,nlogn复杂度
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 class  Solution  {    public  int  lengthOfLIS (int [] nums)  {         int  len  =  1 , n = nums.length;         if  (n == 0 ) {             return  0 ;         }         int [] d = new  int [n + 1 ];         d[len] = nums[0 ];         for  (int  i  =  1 ; i < n; ++i) {             if  (nums[i] > d[len]) {                 d[++len] = nums[i];             } else  {                 int  l  =  1 , r = len, pos = 0 ;                  while  (l <= r) {                     int  mid  =  (l + r) >> 1 ;                     if  (d[mid] < nums[i]) {                         pos = mid;                         l = mid + 1 ;                     } else  {                         r = mid - 1 ;                     }                 }                 d[pos + 1 ] = nums[i];             }         }         return  len;     } } 
 
拓扑排序 
Leetcode 115.序列重建 
证明挺精彩的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 class  Solution  {    public  boolean  sequenceReconstruction (int [] nums, int [][] sequences)  {         int  n  =  nums.length;         int [] indegrees = new  int [n + 1 ];         Set<Integer>[] graph = new  Set [n + 1 ];         for  (int  i  =  1 ; i <= n; i++) {             graph[i] = new  HashSet <Integer>();         }         for  (int [] sequence : sequences) {             int  size  =  sequence.length;             for  (int  i  =  1 ; i < size; i++) {                 int  prev  =  sequence[i - 1 ], next = sequence[i];                 if  (graph[prev].add(next)) {                     indegrees[next]++;                 }             }         }         Queue<Integer> queue = new  ArrayDeque <Integer>();         for  (int  i  =  1 ; i <= n; i++) {             if  (indegrees[i] == 0 ) {                 queue.offer(i);             }         }         while  (!queue.isEmpty()) {             if  (queue.size() > 1 ) {                 return  false ;             }             int  num  =  queue.poll();             Set<Integer> set = graph[num];             for  (int  next : set) {                 indegrees[next]--;                 if  (indegrees[next] == 0 ) {                     queue.offer(next);                 }             }         }         return  true ;     } } 
 
二叉树 
Leetcode 226.翻转二叉树 
1 2 3 4 5 6 7 8 9 10 11 class  Solution  {    public  TreeNode invertTree (TreeNode root)  {         if  (root==null )return  root;         TreeNode temp=root.left;         root.left = root.right;         root.right = temp;         invertTree(root.left);         invertTree(root.right);         return  root;     } } 
 
Leetcode 104.二叉树的最大深度 
1 2 3 4 5 6 7 8 9 10 11 class  Solution  {    public  TreeNode invertTree (TreeNode root)  {         if  (root==null )return  root;         TreeNode temp=root.left;         root.left = root.right;         root.right = temp;         invertTree(root.left);         invertTree(root.right);         return  root;     } } 
 
Leetcode 100.相同的树 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 class  Solution  {    boolean  flag  = true ;     public  boolean  isSameTree (TreeNode p, TreeNode q)  {         findIsSameTree(p,q);         return  flag;     }     public  void  findIsSameTree (TreeNode p,  TreeNode q) {         if  (p!=null &&q!=null ){             findIsSameTree(p.left,q.left);             findIsSameTree(p.right,q.right);         }              if  (p!=null &&q!=null ){             if  (p.val==q.val){                 return ;             }else {                 flag =false ;             }         }else  if (p==null &&q==null ){             return ;         }else {             flag =false ;         }     } } 
 
Leetcode 101.对称二叉树 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 class  Solution  {    boolean  flag  = true ;     public  boolean  isSymmetric (TreeNode root)  {         findIsSymmetric(root,root);         return  flag;     }     public  void  findIsSymmetric (TreeNode a,TreeNode b) {         if  (a==null &&b==null ){             return ;         }else  if  (a!=null &&b!=null ){             if  (a.val!=b.val)flag =false ;             findIsSymmetric(a.left,b.right);             findIsSymmetric(a.right,b.left);         }else {             flag=false ;         }     } } 
 
Leetcode 105.从前序和中序遍历序列构造二叉树 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 TreeNode dfs (int [] preorder, Map<Integer, Integer> inorderMap, int  i, int  l, int  r)  {          if  (r - l < 0 )         return  null ;          TreeNode  root  =  new  TreeNode (preorder[i]);          int  m  =  inorderMap.get(preorder[i]);          root.left = dfs(preorder, inorderMap, i + 1 , l, m - 1 );          root.right = dfs(preorder, inorderMap, i + 1  + m - l, m + 1 , r);               return  root; } TreeNode buildTree (int [] preorder, int [] inorder)  {          Map<Integer, Integer> inorderMap = new  HashMap <>();     for  (int  i  =  0 ; i < inorder.length; i++) {         inorderMap.put(inorder[i], i);     }     TreeNode  root  =  dfs(preorder, inorderMap, 0 , 0 , inorder.length - 1 );     return  root; } 
 
Leetcode 106.从中序和后序遍历序列构造二叉树 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class  Solution  {    public  TreeNode buildTree (int [] inorder, int [] postorder)  {         Map<Integer, Integer> map = new  HashMap <>();         int  length  =  inorder.length;         for  (int  i  =  0 ; i < length; i++) {             map.put(inorder[i], i);         }         return  dfs(inorder, postorder, map, 0 , length - 1 , length - 1 );     }     public  TreeNode dfs (int [] inorder, int [] postorder, Map<Integer, Integer> map, int  left, int  right, int  index)  {         if  (left > right) {             return  null ;         }         int  val  =  postorder[index];         int  mid  =  map.get(val);         TreeNode  node  =  new  TreeNode (val);         node.right = dfs(inorder, postorder, map, mid + 1 , right, index-1 );         node.left = dfs(inorder, postorder, map, left, mid - 1 , index-1 -(right-mid));         return  node;     } } 
 
判断是不是二叉平衡树 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 class  Solution  {    public  boolean  isBalanced (TreeNode root)  {         if (root == null )    return  true ;                  int  left  =  deepFind(root.left);                  int  right  =  deepFind(root.right);                  return  (Math.abs(left - right) < 2  ? true  : false ) && isBalanced(root.left) && isBalanced(root.right);     } 	 	     public  int  deepFind (TreeNode node) {         if (node == null )    return  0 ;         return  Math.max(deepFind(node.left), deepFind(node.right))+1 ;     } } 
 
Leetcode 129.求根节点到叶节点数字之和 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class  Solution  {    int  sum  =  0 ;     public  int  sumNumbers (TreeNode root)  {         StringBuilder  sb  =  new  StringBuilder ("" );         getSum(root,sb);         return  sum;     }     public  void  getSum (TreeNode node,StringBuilder sb) {         if  (node==null )return ;                  StringBuilder  sb2  =  new  StringBuilder ();         String  num  =  String.valueOf(node.val);         sb2.append(sb.toString());         sb2.append(num);         if  (node.left==null &&node.right==null ){             System.out.println(sb2.toString());             sum+=Integer.parseInt(sb2.toString());         }         getSum(node.left,sb2);         getSum(node.right,sb2);     } } 
 
Leetcode 199.二叉树的右视图 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 class  Solution  {    public  List<Integer> rightSideView (TreeNode root)  {         List<Integer>ans = new  ArrayList <Integer>();         Queue<TreeNode>tq = new  LinkedList ();         Queue<Integer>depthQueue = new  LinkedList ();         Map<Integer,Integer>map = new  HashMap ();         tq.add(root);         depthQueue.add(0 );         int  maxDepth  =  -1 ;         while (!tq.isEmpty()){             TreeNode  node  =  tq.poll();             int  depth  =  depthQueue.poll();             if  (node!=null ){                 maxDepth = Math.max(maxDepth,depth);                 map.put(depth,node.val);                 tq.add(node.left);                 tq.add(node.right);                 depthQueue.add(depth+1 );                 depthQueue.add(depth+1 );             }         }         for  (int  i=0 ;i<=maxDepth;i++){             ans.add(map.get(i));         }         return  ans;     } } 
 
Leetcode 117.填充每个节点的下一个右侧节点指针2 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 class  Solution  {    public  Node connect (Node root)  {         Map<Integer,List<Node>>map = new  HashMap ();         Queue<Node> nodeQueue = new  LinkedList ();         Queue<Integer> depthQueue = new  LinkedList ();         int  maxDepth  =  -1 ;         nodeQueue.add(root);         depthQueue.add(0 );         while (!nodeQueue.isEmpty()){             Node  node  =  nodeQueue.poll();             int  depth  =  depthQueue.poll();             if  (node !=null ){                 maxDepth = Math.max(depth,maxDepth);                 if  (!map.containsKey(depth)){                     List<Node>nodeList = new  LinkedList ();                     nodeList.add(node);                     map.put(depth,nodeList);                 }else {                     map.get(depth).add(node);                 }                 nodeQueue.add(node.left);                 nodeQueue.add(node.right);                 depthQueue.add(depth+1 );                 depthQueue.add(depth+1 );             }         }         for  (int  depth=0 ;depth<=maxDepth;depth++){             if  (map.get(depth).size()==1 )continue ;             int  size=map.get(depth).size();             for  (int  index=0 ;index<size-1 ;index++){                 map.get(depth).get(index).next=map.get(depth).get(index+1 );             }         }         return  root;     } } 
 
Leetcode 114.二叉树展开为链表 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class  Solution  {    public  void  flatten (TreeNode root)  {         Queue<TreeNode> q = new  LinkedList ();         q=getPreQueue(root,q);         while (!q.isEmpty()){             TreeNode  node  =  q.poll();             if  (q.size()==0 )break ;             node.left = null ;             node.right = q.peek();         }     }     public  Queue<TreeNode> getPreQueue (TreeNode node,Queue<TreeNode> q) {         if  (node!=null ){             q.add(node);             getPreQueue(node.left,q);             getPreQueue(node.right,q);         }                  return  q;     } } 
 
Leetcode 230.二叉搜索树中第K小的元素 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class  Solution  {    public  int  kthSmallest (TreeNode root, int  k)  {         Queue<TreeNode>q = new  LinkedList ();         q = addToQueue(root,q);         while (k-->0 ){             if  (k==0 )return  q.peek().val;             q.poll();         }         return  -1 ;     }     public  Queue<TreeNode> addToQueue (TreeNode node,Queue<TreeNode>q) {         if  (node!=null ){             addToQueue(node.left,q);             q.add(node);             addToQueue(node.right,q);         }         return  q;     } } 
 
Leetcode 98.验证二叉搜索树 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class  Solution  {    public  boolean  isValidBST (TreeNode root)  {         Queue<TreeNode>q = new  LinkedList ();         q = addToQueue(root,q);         while (!q.isEmpty()){             TreeNode  node  =  q.poll();             if  (q.size()==0 )return  true ;             if  (node.val>=q.peek().val)return  false ;         }         return  true ;     }     public  Queue<TreeNode> addToQueue (TreeNode node,Queue<TreeNode>q) {         if  (node!=null ){             addToQueue(node.left,q);             q.add(node);             addToQueue(node.right,q);         }         return  q;     } } 
 
Leetcode 112.路径总和 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 class  Solution  {    boolean  flag  =  false ;     public  boolean  hasPathSum (TreeNode root, int  targetSum)  {         judgeDFS(root,0 ,targetSum);         return  flag;     }     public  void  judgeDFS (TreeNode node,int  currentNum,int  targetSum) {         if  (node!=null ){             currentNum+=node.val;             if  (currentNum==targetSum&&node.left==null &&node.right==null )flag = true ;             judgeDFS(node.left,currentNum,targetSum);             judgeDFS(node.right,currentNum,targetSum);         }     } } 
 
Leetcode 173.二叉搜索树迭代器 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class  BSTIterator  {    int  currentIndex  =  -1 ;     List<TreeNode> nodeList = new  ArrayList ();      public  BSTIterator (TreeNode root)  {         midOrder(root);     }     public  void  midOrder (TreeNode node) {         if  (node==null )return ;         midOrder(node.left);         nodeList.add(node);         midOrder(node.right);     }          public  int  next ()  {         currentIndex++;         return  nodeList.get(currentIndex).val;     }          public  boolean  hasNext ()  {         int  nextIndex  =  currentIndex+1 ;         return  nextIndex<nodeList.size();     } } 
 
Leetcode 222.完全二叉树的节点个数 
1 2 3 4 5 6 7 8 9 10 11 12 13 class  Solution  {    int  count=0 ;     public  int  countNodes (TreeNode root)  {         getCount(root);         return  count;     }     public  void  getCount (TreeNode node) {         if  (node==null )return ;         count++;         getCount(node.left);         getCount(node.right);     } } 
 
Leetcode 236.二叉树的最近公共祖先 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 class  Solution  {    Map<TreeNode,TreeNode>fatherMap = new  HashMap ();     Map<TreeNode,Integer>depthMap = new  HashMap ();     int  depth=0 ;     public  TreeNode lowestCommonAncestor (TreeNode root, TreeNode p, TreeNode q)  {         getMap(root);         Queue<TreeNode>queue = new  LinkedList ();         Queue<Integer>queue2 = new  LinkedList ();         queue.add(root);         queue2.add(depth);         while (!queue.isEmpty()){             TreeNode  node  =  queue.poll();             int  depth  =  queue2.poll();             if  (node!=null ){                 depthMap.put(node,depth);                 queue.add(node.left);                 queue.add(node.right);                 queue2.add(depth+1 );                 queue2.add(depth+1 );             }         }         int  depth1  =  depthMap.get(p);         int  depth2  =  depthMap.get(q);         TreeNode  ans  =  null ;         TreeNode  p1  =  p;         TreeNode  q1  =  q;         if  (depth1==depth2){             while (true ){                 TreeNode  father1  =  fatherMap.get(p1);                 TreeNode  father2  =  fatherMap.get(q1);                 if  (father1==father2){                     ans = father1;                     return  ans;                 }                 p1 = father1;                 q1 = father2;             }         }else  {             int  gap  =  Math.abs(depth1-depth2);             if  (depth1>depth2){                 for  (int  i=0 ;i<gap;i++){                     p1=fatherMap.get(p1);                 }                                                   if  (p1==q1)return  p1;                 while (true ){                 TreeNode  father1  =  fatherMap.get(p1);                 TreeNode  father2  =  fatherMap.get(q1);                 if  (father1==father2){                     ans = father1;                     return  ans;                     }                 p1 = father1;                 q1 = father2;                 }             }else {                 for  (int  i=0 ;i<gap;i++){                     q1=fatherMap.get(q1);                 }                                                   if  (p1==q1)return  p1;                 while (true ){                 TreeNode  father1  =  fatherMap.get(p1);                 TreeNode  father2  =  fatherMap.get(q1);                 if  (father1==father2){                     ans = father1;                     return  ans;                     }                 p1 = father1;                 q1 = father2;                 }             }         }                      }         public  void  getMap (TreeNode node) {         if  (node ==null )return ;         if  (node.left!=null )fatherMap.put(node.left,node);         if  (node.right!=null )fatherMap.put(node.right,node);         getMap(node.left);         getMap(node.right);     }     } 
 
递归的做法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class  Solution  {    private  TreeNode ans;     public  Solution ()  {         this .ans = null ;     }     private  boolean  dfs (TreeNode root, TreeNode p, TreeNode q)  {         if  (root == null ) return  false ;         boolean  lson  =  dfs(root.left, p, q);         boolean  rson  =  dfs(root.right, p, q);         if  ((lson && rson) || ((root.val == p.val || root.val == q.val) && (lson || rson))) {             ans = root;         }          return  lson || rson || (root.val == p.val || root.val == q.val);     }     public  TreeNode lowestCommonAncestor (TreeNode root, TreeNode p, TreeNode q)  {         this .dfs(root, p, q);         return  this .ans;     } } 
 
Leetcode 102.二叉树的层序遍历 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 class  Solution  {         public  List<List<Integer>> levelOrder (TreeNode root)  {         Map<Integer,List<Integer>> depthNodeListMap = new  HashMap ();         Queue<TreeNode> nodeQueue = new  LinkedList ();         Queue<Integer> depthQueue = new  LinkedList ();         List<List<Integer>> ans = new  ArrayList <List<Integer>>();         if  (root==null )return  ans;         int  firstDepth  =  0 ;         nodeQueue.add(root);         depthQueue.add(firstDepth);         int  maxDepth  =  -1 ;         while (!nodeQueue.isEmpty()){             TreeNode  node  = nodeQueue.poll();             int  depth   =  depthQueue.poll();             if  (node!=null ){                 maxDepth = Math.max(depth,maxDepth);                 if  (!depthNodeListMap.containsKey(depth)){                     List<Integer> list= new  ArrayList ();                     depthNodeListMap.put(depth,list);                 }                 depthNodeListMap.get(depth).add(node.val);                 nodeQueue.add(node.left);                 nodeQueue.add(node.right);                 depthQueue.add(depth+1 );                 depthQueue.add(depth+1 );             }         }                  for  (int  depth=0 ;depth<=maxDepth;depth++){             ans.add(depthNodeListMap.get(depth));         }         return  ans;     } } 
 
Leetcode 427.建立四叉树 
官方题解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 class  Solution  {    public  Node construct (int [][] grid)  {         return  dfs(grid, 0 , 0 , grid.length, grid.length);     }     public  Node dfs (int [][] grid, int  r0, int  c0, int  r1, int  c1)  {         boolean  same  =  true ;         for  (int  i  =  r0; i < r1; ++i) {             for  (int  j  =  c0; j < c1; ++j) {                 if  (grid[i][j] != grid[r0][c0]) {                     same = false ;                     break ;                 }             }             if  (!same) {                 break ;             }         } 		         if  (same) {             return  new  Node (grid[r0][c0] == 1 , true );         } 		         Node  ret  =  new  Node (             true ,             false ,             dfs(grid, r0, c0, (r0 + r1) / 2 , (c0 + c1) / 2 ),             dfs(grid, r0, (c0 + c1) / 2 , (r0 + r1) / 2 , c1),             dfs(grid, (r0 + r1) / 2 , c0, r1, (c0 + c1) / 2 ),             dfs(grid, (r0 + r1) / 2 , (c0 + c1) / 2 , r1, c1)         );         return  ret;     } } 
 
Leetcode 124.二叉树中的最大路径和 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 class  Solution  {    public  int  ans  =  Integer.MIN_VALUE;     public  int  maxPathSum (TreeNode root)  {         getAns(root);         return  ans;     }     public  int  getAns (TreeNode node) {         if  (node==null )return  0 ;         int  leftMax  =  Math.max(getAns(node.left),0 );         int  rightMax  =  Math.max(getAns(node.right),0 );         int  currentNum  =  node.val + leftMax + rightMax;         ans = Math.max(ans,currentNum);                  return  node.val+Math.max(rightMax,leftMax);     } } 
 
Leetcode 637.二叉树的层平均值 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 class  Solution  {    int  maxDepth  =  -1 ;     public  List<Double> averageOfLevels (TreeNode root)  {         List<Double>ans = new  ArrayList ();         Queue<TreeNode>q = new  LinkedList ();         Queue<Integer> depthQ = new  LinkedList ();         Map<Integer,List<TreeNode>> map = new  HashMap ();         q.add(root);         depthQ.add(0 );         while (!q.isEmpty()){             TreeNode  node  =  q.poll();             int  depth  =  depthQ.poll();             if  (node!=null ){                 maxDepth = Math.max(maxDepth,depth);                 List<TreeNode> nodeList = map.getOrDefault(depth,new   ArrayList <TreeNode>());                 nodeList.add(node);                 map.put(depth,nodeList);                 q.add(node.left);                 q.add(node.right);                 depthQ.add(depth+1 );                 depthQ.add(depth+1 );             }         }         for  (int  i  = 0 ;i<=maxDepth;i++){             List<TreeNode> nodeList = map.get(i);             if  (nodeList!=null )             ans.add(getAverage(nodeList));         }         return  ans;     }     public  double  getAverage (List<TreeNode> nodeList) {         int  size= nodeList.size();         double  sum  =  0 ;         for  (TreeNode node:nodeList){             sum =sum+node.val;         }         return  sum/size;     } } 
 
Leetcode 103.二叉树的锯齿形层序遍历 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 class  Solution  {    int  maxDepth  = -1 ;     public  List<List<Integer>> zigzagLevelOrder (TreeNode root)  {         List<List<Integer>> ans = new  ArrayList <List<Integer>>();         Queue<TreeNode>q = new  LinkedList ();         Map<Integer,List<Integer>>map = new  HashMap ();         Queue<Integer> depthQ = new  LinkedList ();         q.add(root);         depthQ.add(0 );         while (!q.isEmpty()){             TreeNode  node  =  q.poll();             int  depth  =  depthQ.poll();             if  (node!=null ){                 maxDepth = Math.max(depth,maxDepth);                 List<Integer>list = map.getOrDefault(depth,new  ArrayList <Integer>());                 list.add(node.val);                 map.put(depth,list);                 q.add(node.left);                 q.add(node.right);                 depthQ.add(depth+1 );                 depthQ.add(depth+1 );             }         }         for  (int  i=0 ;i<=maxDepth;i++){             List<Integer>list = map.get(i);             if  (i%2 ==0 ){                 ans.add(list);             }else {                 Collections.reverse(list);                 ans.add(list);             }         }         return  ans;     } } 
 
Leetcode 530.二叉搜索树的最小绝对差 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 class  Solution  {    Queue<Integer>q = new  PriorityQueue <Integer>((a,b)->a-b);     public  int  getMinimumDifference (TreeNode root)  {         preOrder(root);         int  ans  =  Integer.MAX_VALUE;         while  (!q.isEmpty()){             int  a  =  q.poll();             if  (q.isEmpty())break ;             int  b  =  q.peek();             ans = Math.min(ans,Math.abs(a-b));         }         return  ans;     }     public  void  preOrder (TreeNode node) {         if  (node==null )return ;         q.add(node.val);         preOrder(node.left);         preOrder(node.right);     } } 
 
堆 
Leetcode 373.查找和最小的K对数字 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 class  Solution  {    public  List<List<Integer>> kSmallestPairs (int [] nums1, int [] nums2, int  k)  {         PriorityQueue<int []> pq = new  PriorityQueue <>(k, (o1, o2)->{             return  nums1[o1[0 ]] + nums2[o1[1 ]] - nums1[o2[0 ]] - nums2[o2[1 ]];         });         List<List<Integer>> ans = new  ArrayList <>();         int  m  =  nums1.length;         int  n  =  nums2.length;         for  (int  i  =  0 ; i < Math.min(m, k); i++) {             pq.offer(new  int []{i,0 });         }         while  (k-- > 0  && !pq.isEmpty()) {             int [] idxPair = pq.poll();             List<Integer> list = new  ArrayList <>();             list.add(nums1[idxPair[0 ]]);             list.add(nums2[idxPair[1 ]]);             ans.add(list);             if  (idxPair[1 ] + 1  < n) {                 pq.offer(new  int []{idxPair[0 ], idxPair[1 ] + 1 });             }         }                  return  ans;     } } 
 
Leetcode 215.数组中的第K个最大元素 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class  Solution  {    public  int  findKthLargest (int [] nums, int  k)  {         Queue<Integer>q = new  PriorityQueue (new  Comparator <Integer>(){             public  int  compare (Integer a,Integer b) {                 return  b-a;             }         });         for  (int  num:nums){             q.add(num);         }         while (k-->0 ){             if  (k==0 )return  q.poll();             q.poll();         }         return  0 ;     } } 
 
数学 
Leetcode 201.数字范围按位与 
1 2 3 4 5 6 7 8 9 10 11 12 13 class  Solution  {    public  int  rangeBitwiseAnd (int  left, int  right)  {         int  move  =  0 ;         int  m=left;         int  n=right;         while  (m!=n){             m=m>>1 ;             n=n>>1 ;             move++;         }         return  m<<move;     } } 
 
Kadane算法 
Leetcode 53.最大子数组和 
常规用前缀和会超时
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class  Solution  {    public  int  maxSubArray (int [] nums)  {         int  length  =  nums.length;         int  prefixSum[] = new  int [length+1 ];         prefixSum[0 ]=0 ;         for  (int  i=0 ;i<length;i++){             prefixSum[i+1 ]=prefixSum[i]+nums[i];         }         int  ans  =  Integer.MIN_VALUE;         for  (int  i=0 ;i<length;i++){             for  (int  j=i+1 ;j<=length;j++){                 int  gap  =  prefixSum[j]-prefixSum[i];                 ans = Math.max(gap,ans);             }         }         return  ans;     } } 
 
优化后的前缀和
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class  Solution  {    public  int  maxSubArray (int [] nums)  {         int  length  =  nums.length;         int  prefixSum[] = new  int [length+1 ];         prefixSum[0 ]=0 ;         for  (int  i=0 ;i<length;i++){             prefixSum[i+1 ]=prefixSum[i]+nums[i];         }         int  ans  =  Integer.MIN_VALUE;         int  p=0 ;         for  (int  i=1 ;i<=length;i++){             if  (prefixSum[p]>=prefixSum[i]){                 ans = Math.max(ans, prefixSum[i]-prefixSum[i-1 ]);                 p=i;             }else {                 ans = Math.max(ans, prefixSum[i]-prefixSum[p]);             }         }         return  ans;     } }