LeetCode知识点整理

1、Scanner 输入:

import java.util.Scanner;
 
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        // 读取整数
        int num = scanner.nextInt();
        // 读取一行字符串
        String line = scanner.nextLine();
        scanner.close();
    }
}

2、原码、反码、补码

原码:十进制数据的二进制表示形式,最左边是符号位,0为正,1为负。

正数的原码、反码、补码一样。

负数的原码符号位不变,其余位取反就是负数的反码;负数的反码+1就是负数的补码。

计算机中数字存储和的计算都是使用数字的补码。

示例:+3
原码:0000 0011
反码:0000 0011
补码:0000 0011

示例:-3
原码:1000 0011
反码:1111 1100
补码:1111 1101

3、二进制、八进制、十进制、十六进制

以十进制数42为例

十进制:
int decimalNumber = 42;

‌二进制:
int binaryNumber = 0b101010; // 以0b或0B作为前缀

八进制:
int octalNumber = 052; // 以0作为前缀

十六进制:
int hexNumber = 0x2a; // 以0x或0X作为前缀

4、Integer 等包装类

int intValue() 返回Integer对象的int类型值。

static int MAX_VALUE int的最大值
 
static int MIN_VALUE int的最小值


其他进制-->10进制:

static int parseInt(String s) 将字符串以十进制进行解析。

static int parseInt(String s, int radix) 将字符串以指定进制进行解析。
示例:Integer.parseInt("2a", 16); // 42

static Integer valueOf(String s) 将字符串以十进制进行解析。
 
static Integer valueOf(String s, int radix) 将字符串以指定进制进行解析。
示例:Integer.valueOf("2a", 16); // 42


其他进制-->10进制:

static String toString(int i) 返回int的十进制字符串对象。

static String toString(int i, int radix) 返回int的指定进制字符串对象。
示例:Integer.toString(42, 16); // 2a


static String toBinaryString(int i) 返回2进制形式的字符串。
示例:
String str = Integer.toBinaryString(3);  // 11
str =String.format("start:%8s", str); // start:      11
str = str.replace(" ", "0"); // start:00000011

static String toHexString(int i) 返回16进制形式的字符串。
示例:
String str = Integer.toHexString(3);  // 3
str = String.format("start:%2s", str); // start: 3
str = str.replace(" ", "0"); // start:03


static String format(String format, Object... args) 返回格式化字符串。
示例:
String str = String.format("start:%d", 1);  // start:1
str = String.format("start:%2d", 1); // start: 1
str = str.replace(" ", "0"); // start:01

5、移位运算符

<<:右边用0填充。

>>>:左边用0填充。

>>:左边用最高位相同的值填充。

6、按位运算符

按位与 &      按位或 |      按位异或 ^      按位非 ~

位值位值&|^
00000
01011
11110

7、String

常用构造方法:
new String() 创建一个空字符串对象。

new String(byte[] bytes, String charsetName) 创建一个由指定字符集解码的字符串对象。

new String(char[] value) 创建一个包含字符序列的字符串对象。

new String(StringBuilder builder) 创建一个表示builder字符序列的字符串对象。

常用API:
char charAt(int index) 返回指定索引处的charint compareTo(String anotherString) 按字典顺序比较两个字符串。
示例:
"1".compareTo("9") // <0
"1".compareTo("1") // 0
"9".compareTo("1") // >0

int compareToIgnoreCase(String str) 按字典顺序比较两个字符串,忽略大小写。

boolean	contains(CharSequence s) 当且仅当此字符串包含指定的字符序列时才返回trueboolean	startsWith(String prefix) 测试此字符串是否以指定的前缀开头。

boolean	startsWith(String prefix, int toffset) 测试此字符串在指定索引开始的子字符串是否以指定的前缀开头,toffset从0开始。

boolean	endsWith(String suffix) 测试此字符串是否以指定的后缀结尾。

boolean	equals(Object anObject) 将此字符串与指定对象进行比较。

boolean	equalsIgnoreCase(String anotherString) 将此字符串与anotherString比较,忽略大小写。

byte[] getBytes(String charsetName) 使用charsetName字符集将此字符串编码为字节序列,将结果存储到新的字节数组中。

int indexOf(String str) 返回指定子字符串第一次出现在字符串内的索引。

int indexOf(String str, int fromIndex) 返回指定子字符串第一次出现在字符串中的索引,从fromIndex开始搜索,fromIndex从0开始。

int lastIndexOf(String str) 返回指定子字符串最后一次出现在字符串中的索引。

int lastIndexOf(String str, int fromIndex) 返回指定子字符串最后一次出现在字符串中的索引,从fromIndex开始向后搜索,fromIndex从0开始。

int length() 返回此字符串的长度。

boolean	matches(String regex) 判定此字符串是否匹配给定的正则表达式regex。

String replace(char oldChar, char newChar) 返回用newChar替换了所有oldChar后的字符串。

String replaceAll(String regex, String replacement) 返回用replacement替换了所有匹配正则表达式regex子字符串后的字符串。

String replaceFirst(String regex, String replacement) 返回用replacement替换了第一个匹配正则表达式regex子字符串后的字符串。

String[] split(String regex) 以regex将此字符串进行分割。

String substring(int beginIndex) 返回一个从beginIndex开始的子字符串,beginIndex从0开始。

String substring(int beginIndex, int endIndex) 返回一个从beginIndex到endIndex的子字符串,beginIndex从0开始。

char[] toCharArray() 将此字符串转换为新的字符数组。

String toLowerCase() 将字符串所有字符转换为小写。

String toUpperCase() 将字符串所有字符转换为大写。

String trim() 返回一个删除任何前导和尾随空格的字符串。

static String valueOf(int i) 返回int参数的字符串int形式。


字符串排序示例:
import java.util.Arrays;

public class MainTest {
    public static void main(String[] args) {
        String str = "Hello World";
        char[] charArray = str.toCharArray();

        Arrays.sort(charArray);

        String sortedString = new String(charArray);
        System.out.println(sortedString);  // 输出: HWdellloor
    }
}


字符串统计示例:
import java.util.HashMap;
import java.util.Map;

public class MainTest {
    public static void main(String[] args) {
        String str = "Hello World";
        Map<Character, Integer> countMap = new HashMap<>();

        for (char ch : str.toCharArray()) {
            countMap.put(ch, countMap.getOrDefault(ch, 0) + 1);
        }

        System.out.println(countMap);  // 输出:{ =1, r=1, d=1, e=1, W=1, H=1, l=3, o=2}
    }
}

8、StringBuilder

常用构造方法:
new StringBuilder() 创建一个初始容量为16个字符的字符串构建器。

new StringBuilder(String str) 创建一个初始化为指定字符串内容的字符串构建器。

常用API:
StringBuilder append(String str) 将指定的字符串添加到此字符序列末尾。

StringBuilder delete(int start, int end) 删除此字符序列从start到end的字符,左闭右开,start从0开始。

StringBuilder deleteCharAt(int index) 删除这个字符序列中指定位置的charStringBuilder insert(int offset, String str) 将str插入到此字符序列指定位置。

StringBuilder replace(int start, int end, String str) 将start到end用str替换。

StringBuilder reverse() 反转此字符序列。

9、Collection

Collection<E>I)集合
  |
  |-- List<E>I)有序的 Collection (与元素插入顺序一致),也称为序列。
  |    |
  |    |-- Stack<E>C)栈,后进先出。
  |    |
  |    |-- ArrayList<E>C)使用数组实现。
  |    |
  |    |-- LinkedList<E>C)使用双向链表实现。
  |
  |-- Set<E>I)不含重复元素的 Collection,最多包含一个 null 元素。
  |    |
  |    |-- HashSet<E>C)无序的,与元素插入顺序无关。
  |    |
  |    |-- LinkedHashSet<E>C)有序的,与元素插入顺序一致。
  |    |
  |    |-- TreeSet<E>C)使用元素的自然顺序排序,或者根据提供的 Comparator 排序。
  |
  |-- Queue<E>I)队列,先进先出;从队列尾部添加元素,从队列头部删除元素。
  |    |
  |    |-- PriorityQueue<E>C)优先队列
  |    |
  |    |-- LinkedList<E>C)双向队列,支持在队列两端插入和删除元素。



Stack常用APIboolean empty() 判断栈是否为空。

E peek() 返回栈顶对象,而不将其从栈中删除。栈为空抛异常。

E pop() 返回栈顶对象,并将其从栈中删除。栈为空抛异常。

E push(E item) 将对象添加到栈顶。
 
int search(Object o) 返回对象在此栈上的位置,栈顶为1ArrayList常用APIboolean	add(E e) 将指定的元素追加到此列表的末尾。

void add(int index, E element) 在此列表中的指定位置插入指定的元素。

boolean	addAll(Collection<? extends E> c) 按指定集合中的所有元素追加到此列表的末尾。

boolean	addAll(int index, Collection<? extends E> c) 将指定集合中的所有元素插入到此列表中,从指定的位置开始。

boolean contains(Object o) 如果此列表包含指定的元素,则返回trueboolean containsAll(Collection<?> c) 如果此集合包含指定集合中的所有元素,则返回trueboolean retainAll(Collection<?> c) 获取两个集合的交集,即只保留原集合与指定集合相同的元素。

E set(int index, E element) 用指定的元素替换此列表中指定位置的元素。

E remove(int index) 删除该列表中指定位置的元素。

boolean remove(Object o) 从列表中删除第一个指定的元素。

boolean	removeAll(Collection<?> c) 从此列表中删除指定集合中包含的所有元素。

boolean	removeIf(Predicate<? super E> filter) 删除此集合中满足给定谓词的所有元素。
示例:
List<String> list = new ArrayList<>();
Collections.addAll(list, "a", "b");
list.removeIf(x -> x.equals("a")); // [b]

boolean equals(Object o) 比较两个列表是否相等,两个列表都具有相同的大小,并且两个列表中所有相应的元素对相等。

void replaceAll(UnaryOperator<E> operator) 对列表的每个元素应用一个函数,并用函数返回的结果替换原值。
示例:
List<String> list = new ArrayList<>();
Collections.addAll(list, "a", "b");
list.replaceAll(x -> x + "x"); // [ax, bx]

E get(int index) 返回此列表中指定位置的元素。

void clear() 从列表中删除所有元素。

boolean	isEmpty() 如果此列表不包含元素,则返回trueint size() 返回此列表中的元素数。

Iterator<E> iterator() 返回该列表的迭代器。

int indexOf(Object o) 返回此列表中指定元素的第一次出现的索引,如果此列表不包含元素,则返回-1int lastIndexOf(Object o) 返回此列表中指定元素的最后一次出现的索引,如果此列表不包含元素,则返回-1void sort(Comparator<? super E> c) 使用提供的Comparator对此列表进行排序。

Stream<E> stream() 返回此集合的StreamObject[] toArray() 以正确的顺序返回一个包含此列表中所有元素的数组。

<T> T[]	toArray(T[] a) 以正确的顺序返回一个包含此列表中所有元素的数组; 返回的数组的运行时类型是指定数组的运行时类型。
示例:
List<String> list = new ArrayList<>();
Collections.addAll(list, "a", "b");
String[] arr = list.toArray(new String[0]); // [a, b]




LinkedList常用API:
void push(E e) 将元素添加到列表头部。

E peek() 返回列表头部元素,并不删除;如果没有元素返回nullE poll() 返回并删除列表头部元素;如果没有元素返回nullboolean	offer(E e) 将指定的元素添加到此列表的尾部,添加成功返回true,失败返回falsePriorityQueue:
PriorityQueue() 创建一个初始容量为11的优先队列。

PriorityQueue(Comparator<? super E> comparator) 创建一个初始容量为11的优先队列,并且其元素根据指定的比较器进行排序。

常用APIboolean add(E e) 将指定的元素插入此优先级队列。

void clear() 从这个优先级队列中移除所有元素。

boolean contains(Object o) 如果此队列包含指定的元素,则返回trueboolean containsAll(Collection<?> c) 如果此集合包含指定集合中的所有元素,则返回trueIterator<E> iterator() 返回此队列中元素的迭代器。

E peek() 返回列表头部元素,并不删除;如果没有元素返回nullE poll() 返回并删除列表头部元素;如果没有元素返回nullboolean remove(Object o) 从队列中删除一个指定元素(如果存在)。

Object[] toArray() 以正确的顺序返回一个包含此列表中所有元素的数组。

<T> T[] toArray(T[] a) 以正确的顺序返回一个包含此列表中所有元素的数组; 返回的数组的运行时类型是指定数组的运行时类型。
示例:
PriorityQueue<String> priorityQueue = new PriorityQueue();
Collections.addAll(priorityQueue, "c", "a", "b");
String[] arr = priorityQueue.toArray(new String[0]); // [a, c, b]

10、Map

Map<K,V>I)键值对(key-value)|
 |-- HashMap<K,V>C)最多只允许一条记录的 key 为 null;无序的,与元素插入顺序无关。
 |
 |-- LinkedHashMap<K,V>C)有序的,与元素插入顺序一致。  
 |
 |-- TreeMap<K,V>C)最多只允许一条记录的 key 为 null;根据key的自然顺序排序,或者根据提供的 Comparator 排序。



HashMap常用APIvoid clear() 删除所有键值对。

boolean containsKey(Object key) 如果此映射包含指定键的映射,则返回trueboolean containsValue(Object value) 如果此映射将一个或多个键映射到指定值,则返回trueboolean equals(Object o) 将指定的对象与此映射进行比较。 

void forEach(BiConsumer<? super K,? super V> action) 对此映射中的每个键值执行给定的操作,直到所有条目都被处理或操作引发异常。
示例:
HashMap<String, String> hashMap = new HashMap();
hashMap.put("a","aa");
hashMap.put("b","bb");
hashMap.forEach((x, y) -> System.out.println(x + "->" + y));  // a->aa  b->bb

V get(Object key) 返回指定键所映射的值,如果没有则返回nullboolean	isEmpty() 如果此映射不包含键值对,则返回trueint size() 返回此映射中键值对的数量。

Set<K> keySet() 返回此映射中包含的键的Set集合。

Collection<V> values() 返回此映射中包含的值的Collection列表。

V put(K key, V value) 新增键值对。

void putAll(Map<? extends K,? extends V> m) 添加映射m,如果有相同的键值对替换原键值对。

V putIfAbsent(K key, V value) 如何不存在的key才新增,避免替换原键值对。

V remove(Object key) 从该映射中删除指定键的映射(如果存在)。

boolean remove(Object key, Object value) 仅当与指定键值对相等时才删除。

boolean	replace(K key, V oldValue, V newValue) 仅当key-oldValue存在,才能用newValue替换oldValue。

void replaceAll(BiFunction<? super K,? super V,? extends V> function) 将键值对的值替换为对该键值对调用给定函数的结果,直到所有条目都被处理或该函数抛出异常。
示例:
Map<String, String> map = new HashMap<>();
map.put("a", "b");
map.replaceAll((k,v) -> v.concat("d"));
System.out.println(map); // {a=bd}

V compute(K key, BiFunction<? super K,? super V,? extends V> remappingFunction) 如果key存在,则计算后更新value;如果key不存在,则将key-value插入。
示例:
Map<String, String> map = new HashMap<>();
map.put("a", "b");
map.compute("a", (k,v) -> v.concat("d"));
System.out.println(map); // {a=bd}

Map<String, String> map = new HashMap<>();
map.compute("a", (k,v) -> "d");
System.out.println(map); // {a=d};这里不能 v.concat("d"),会报空指针异常。

V computeIfAbsent(K key, Function<? super K,? extends V> mappingFunction) 如果key不存在才会执行函数,并将结果插入。

V computeIfPresent(K key, BiFunction<? super K,? super V,? extends V> remappingFunction) 如果key存在才会执行函数,并用结果替换原value。
如果指定的密钥的值存在且非空,则尝试计算给定密钥及其当前映射值的新映射。

V getOrDefault(Object key, V defaultValue) 如何存在key,返回对于value;如果不存在key,返回后面的默认值。
示例:
List<String> list = new ArrayList<>();
Collections.addAll(list, "wang1", "wang3");

Map<String, List<String>> map = new HashMap<>();
map.put("wang", list);

list = map.getOrDefault("wang", new ArrayList<String>());
System.out.println(list); // [wang1, wang3]

list = map.getOrDefault("zhang", new ArrayList<String>());
System.out.println(list); // []



TreeMap常用APIK firstKey() 返回此映射中当前的第一个(最低)键。

K lastKey() 返回此映射中当前的最后一个(最高)键。

K ceilingKey(K key) 返回大于或等于给定键的最小键,如果没有这样的键,则返回nullK floorKey(K key) 返回小于或等于给定键的最大键,如果没有这样的键,则返回null

11、Iterator迭代器

定义:
public interface Iterator<E> 对 collection 进行迭代的迭代器。

APIboolean hasNext() 如果仍有元素可以迭代,则返回 trueE next() 返回迭代的下一个元素。 

void remove() 从集合中删除迭代器最后访问的元素(可选操作)。 

12、Comparator比较器

定义:
public interface Comparator<T> 强制对某些对象集合进行总排序的比较函数。

APIint compare(T o1, T o2) 比较用来排序的两个参数。 注:o1 - o2 是升序。

boolean equals(Object obj) 指示某个其他对象是否“等于”此 Comparator。 

示例:
List<Integer> list = new ArrayList<>();
Collections.addAll(list, 3, 2, 1);
Collections.sort(list, (o1, o2) -> o1 - o2);
System.out.println(list); // [1, 2, 3]

13、Collections类

boolean Collections.addAll(Collection<? super T> c, T... elements) 将多个元素添加到集合中,每个元素用逗号隔开。 

boolean Collections.disjoint(Collection<?> c1, Collection<?> c2) 判定两个集合没有相同的元素,没有相同元素返回true,有相同元素返回falsevoid Collections.fill(List<? super T> list, T obj) 使用指定元素替换list中的所有元素,有元素才会替换。

static int frequency(Collection<?> c, Object o) 返回集合中指定元素出现的次数。 

void Collections.sort(List<T> list) 根据元素的自然顺序对指定列表按升序进行排序。 

void Collections.sort(List<T> list, Comparator<? super T> c) 根据指定的比较器对指定列表进行排序。 

T Collections.max(Collection<? extends T> coll) 根据元素的自然顺序,返回给定 coll 的最大元素。 

T Collections.max(Collection<? extends T> coll, Comparator<? super T> comp) 根据指定比较器比较,返回给定 coll 的最大元素。 

T Collections.min(Collection<? extends T> coll) 根据元素的自然顺序 返回给定 coll 的最小元素。 

T Collections.min(Collection<? extends T> coll, Comparator<? super T> comp) 根据指定比较器比较,返回给定 coll 的最小元素。 

void Collections.reverse(List<?> list) 反转指定列表中元素的顺序。 

void swap(List<?> list, int i, int j) 交换指定元素在列表中的位置。

14、Arrays类

int[] Arrays.copyOf(int[] original, int newLength) 返回指定长度为newLength的数组,它的前newLength个元素为数组original的前newLength个元素,如果超出数组original的长度则用0填充。

int[] Arrays.copyOfRange(int[] original, int from, int to) 返回将指定数组的指定范围复制到新数组中。

boolean Arrays.equals(int[] a, int[] a2) 如果指定的两个int数组每个元素都相等,则返回trueboolean Arrays.deepEquals(Object[] a1, Object[] a2) 如果指定的两个多维数组每个元素都相等,则返回truestatic void fill(int[] a, int val) 用指定int值替换数组中的每一个元素。

static void fill(int[] a, int fromIndex, int toIndex, int val) 用指定int值替换数组中的从fromIndex到toIndex的元素。

String Arrays.toString(int[] a) 返回指定数组内容的字符串表示形式。

String Arrays.deepToString(Object[] a) 返回指定多维数组内容的字符串表示形式。

void Arrays.sort(int[] a) 按照自然顺序排列数组。

void Arrays.sort(int[] a, int fromIndex, int toIndex) 按自然顺序排列数组的指定范围。

void Arrays.sort(T[] a, Comparator<? super T> c) 根据指定的比较器对指定的对象数组进行排序。
只能用于对象数组排序,不能用于基本数据类型。Arrays.sort(a, (x, y) -> x.compareTo(y)) 升序。

void Arrays.sort(T[] a, int fromIndex, int toIndex, Comparator<? super T> c) 根据指定的比较器对指定的对象数组的指定范围进行排序。
只能用于对象数组排序。

Stream<T> Arrays.stream(T[] array) 返回array的Stream流。

15、Math常用API

static int abs(int a) 返回int值的绝对值。

static int max(int a, int b) 返回两个值中的较大者。

static int min(int a, int b) 返回两个值中的较小者。

16、Stream流

static <T> Stream<T> empty() 返回一个空的顺序流。

static <T> Stream<T> of(T t) 返回包含单个元素的顺序流。
static <T> Stream<T> of(T... values) 返回其元素为指定值的有序顺序流。
示例:
Stream<String> s = Stream.of("a", "b", "c");
Stream<String> ss = Stream.of("a!b!c".split("!"));

数组与List互相转换:
List<String> strList = Stream.of("a", "b").collect(Collectors.toList());
String[] strArr = strList.toArray(new String[0]);
strList = Arrays.stream(strArr).collect(Collectors.toList());

分组:
Map<String, List<User>> mapList = userList.stream().collect(Collectors.groupingBy(User::getAge));


boolean	allMatch(Predicate<? super T> predicate) 所有元素匹配成功,返回true

boolean	anyMatch(Predicate<? super T> predicate) 任意一个元素匹配成功,返回trueboolean	noneMatch(Predicate<? super T> predicate) 所有元素都不匹配,返回truelong count() 返回当前流中元素的数量。这是一个终止操作。

Stream<T> distinct() 根据Object.equals(Object)返回去重后的流。

Stream<T> filter(Predicate<? super T> predicate)  返回满足 predicate 条件的流。


<R> Stream<R> map(Function<? super T,? extends R> mapper)  返回一个流,它包含将 mapper 应用于当前流中所有元素产生的结果。

<R> Stream<R> flatMap(Function<? super T,? extends Stream<? extends R>> mapper) 返回一个流,它是通过将 mapper 应用于当前流中所有元素产生的结果连接到一起而获得的。
示例:
List<List<String>> listList = new ArrayList<>();
List<String> ls1 = Stream.of("c", "a").collect(Collectors.toList());
listList.add(ls1);
List<String> ls2 = Stream.of("e", "b").collect(Collectors.toList());
listList.add(ls2);
List<String> strList = listList.stream().flatMap(list -> list.stream().sorted()).collect(Collectors.toList());
strList.forEach(System.out::print); // acbe


void forEach(Consumer<? super T> action) 此流的每个元素会传递给 action。结束函数,不再返回流。

Stream<T> peek(Consumer<? super T> action) 此流的每个元素会传递给 action。返回原来的流。

Stream<T> limit(long maxSize) 返回由该流前 maxSize 元素组成的流。

Stream<T> skip(long n) 返回由该流除前 n 个元素之外的元素组成的流。

static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b) 创建一个延迟串联的流。


Stream<T> sorted()  返回由该流的元素组成的流,并根据自然顺序排序。

Stream<T> sorted(Comparator<? super T> comparator) 返回由该流的元素组成的流,并根据提供的Comparator对其进行排序。

17、Optional 类

定义:
public final class Optional<T> extends Object  
源码:
public final class Optional<T> {
     /**
     * 如果为null,则表示不存在任何值;如果非空,则为该值。
     */
    private final T value;
}


API:
static <T> Optional<T> empty() 返回一个空的Optional实例。
示例:
Optional optional = Optional.empty();
System.out.println(optional); // Optional.empty


boolean	equals(Object obj) 表示其他某个对象是否“等于”此Optional。
源码:
Objects.equals(value, other.value) // 实际equals的是Optional实例的value。


T get() 存在值,则返回该值,否则抛出NoSuchElementExceptionboolean isPresent()  存在值,返回true,否则返回falsevoid ifPresent(Consumer<? super T> consumer)  如果存在值,则传给 consumer,否则什么也不做。


static <T> Optional<T> of(T value)  返回指定值的Optional,如果为null,抛出NPE异常。

static <T> Optional<T> ofNullable(T value) 返回指定值的Optional,如果为null,则返回一个空Optional。
示例:
Optional o1 = Optional.ofNullable("a"); // Optional[a]
Optional o2 = Optional.ofNullable(null); // Optional.empty


T orElse(T other) 如果存在,返回该值,否则返回other。
示例:
Optional.ofNullable("a").orElse("b"); // a
Optional.ofNullable(null).orElse("b"); // b


T orElseGet(Supplier<? extends T> other) 如果存在,返回该值,否则调用other,然后返回该调用的结果。
示例:
String str = Optional.ofNullable(null).orElseGet(() -> "other"); // other


String toString() 返回此Optional的字符串表示。
源码:
public String toString() {
    return value != null ? String.format("Optional[%s]", value) : "Optional.empty";
}

18、二叉树

树的高度、深度、层:

高度(山)  深度(井)  层(层)
 3          0        1
 2          1        2
 1          2        3
 0          3        4
---------------------------

存储方法:

二叉树基于数组的顺序存储法:
int[] tree = new int[]{0, 1, 2, 3, 4, 5, -1};
如果节点存储在下标为 i 的位置,那它左子节点存储在下标为 2*i+1 的位置,它右子节点存储在为 2*i+2 的位置。
如果节点存储在下标为 i 的位置,那它的父节点存储在下标为 (i-1)/2 的位置。

二叉树基于引用的二叉链式存储法:
class Node {
	int value;
	Node left;
	Node right;
}


前序遍历:
void preOrder(int[] tree, int i) {
  if (i >= tree.length || tree[i] == -1) {
		return;
  }
  tree[i];
  preOrder(tree, 2*i+1);
  preOrder(tree, 2*i+2);
}

void preOrder(Node node) {
  if (node == null) {
  	return;
  }
  node.value;
  preOrder(node.left);
  preOrder(node.right);
}


中序遍历:
void inOrder(int[] tree, int i) {
  if (i >= tree.length || tree[i] == -1) {
		return;
  }
  inOrder(tree, 2*i+1);
  tree[i];
  inOrder(tree, 2*i+2);
}

void inOrder(Node node) {
  if (node == null) {
  	return;
  }
  inOrder(node.left);
  node.value;
  inOrder(node.right);
}


后序遍历:
void postOrder(int[] tree, int i) {
  if (i >= tree.length || tree[i] == -1) {
		return;
  }
  postOrder(tree, 2*i+1);
  postOrder(tree, 2*i+2);
  tree[i];
}

void postOrder(Node node) {
  if (node == null) {
  	return;
  }
  postOrder(node.left);
  postOrder(node.right);
  node.value;
}

19、递归算法:

递归需要满足的三个条件:
1.一个问题的解可以分解为几个子问题的解
2.这个问题与分解之后的子问题,除了数据规模不同,求解思路完全一样
3.存在递归终止条件

写递归代码最关键的是写出递推公式,找到终止条件。

递归示例讲解:
假如这里有n个台阶,每次你可以跨1个台阶或者2个台阶,请问走这n个台阶有多少种走法?

实际上,可以根据第一步的走法把所有走法分为两类,第一类是第一步走了1个台阶,另一类是第一步走了2个台阶。
所以n个台阶的走法就等于先走1阶后,n-1个台阶的走法 加上先走2阶后,n-2个台阶的走法。
用公式表示就是:f(n) = f(n-1) + f(n-2)

再来看下终止条件
f(1) = f(0) + f(-1)
f(2) = f(1) + f(0)
f(3) = f(2) + f(1)
f(0)f(-1)没有意义,所以n=3时实际才有意义,那么终止条件就是f(2)f(1)。

把递归终止条件和刚刚得到的递推公式放到一起就是这样的:
f(1) = 1;
f(2) = 2;
f(n) = f(n-1)+f(n-2)
最终的递归代码是这样的:
int f(int n) {
  if (n == 1) return 1;
  if (n == 2) return 2;
  return f(n-1) + f(n-2);
}


递归代码需要注意的问题:
1、堆栈溢出
如果递归求解的数据规模很大,调用层次很深,一直压入栈,就会有堆栈溢出的风险。

如何避免出现堆栈溢出呢?
我们可以通过在代码中限制递归调用的最大深度的方式来解决这个问题。递归调用超过一定深度(比如1000)之后,我们就不继续往下再递归了,直接返回报错。

2、重复计算
例如:
f(5) = f(4) + f(3)
f(4) = f(3) + f(2)
f(3)就被重复计算。

如何避免出现重复计算呢?
可以通过一个数据结构(比如散列表)来保存已经求解过的f(k)。当递归调用到f(k)时,先看下是否已经求解过了。如果是,则直接从散列表中取值返回。

public int f(int n) {
  if (n == 1) return 1;
  if (n == 2) return 2;
  
  // hashMap,key是n,value是f(n)
  if (hashMap.containsKey(n)) {
    return hashMap.get(n);
  }
  
  int ret = f(n-1) + f(n-2);
  hashMap.put(n, ret);
  return ret;
}

20、计算表达式的值

中缀表达式:日常通用的算术和逻辑公式表示方法,如:3 + 2 。

后缀表达式:又称逆波兰式,操作符以后缀形式位于两个运算数之后,如:3 2 + 。

前缀表达式:又称波兰式,操作符以前缀形式位于两个运算数之前,如:+ 3 2 。


中缀表达式转后缀表达式
从左至右依次遍历中缀表达式中各个元素,需要准备一个后缀表达式list和一个栈,
1、元素为 运算数
直接加入list。
2、元素为 左括号
直接入栈(注:左括号入栈后优先级降至最低)。
3、元素为 右括号
直接出栈,并将出栈元素依次加入list,直到栈顶元素为左括号,左括号也要出栈,但不加入list。
4、元素为 操作符
若栈空,直接入栈。若栈非空,判断栈顶操作符,若栈顶操作符优先级低于该操作符,该操作符入栈;
否则一直出栈,并将出栈元素依次加入list,直到栈空或栈顶操作符优先级低于该操作符,该操作符再入栈。
5、
重复以上步骤直至遍历完成中缀表达式,接着判断栈是否为空,非空则直接出栈,并将出栈元素依次加入list。


后缀表达式的计算
从左至右依次遍历后缀表达式各个元素,需要准备一个栈,
1、元素为 运算数 :
直接入栈
2、元素为 操作符 :
连续出栈两次,使用出栈的两个数据进行相应计算,并将计算结果入栈。(注意:第一个出栈的运算数为 a ,第二个出栈的运算数为 b ,操作符为 - ,则应计算 b-a )。
3、重复以上步骤直至遍历完成后缀表达式,最后栈中的数据就是中缀表达式的计算结果。

21、 大端序和小端序

大端序:将高位字节存储在低地址,低位字节存储在高地址。
比如对于32位整数 0x12345678 ,在大端序存储时,内存地址从低到高依次存放的字节是 0x120x340x560x78 。
就像正常阅读文字一样,从左到右高位在前,符合人类的阅读习惯。
 
小端序:与大端序相反,将低位字节存储在低地址,高位字节存储在高地址。
以32位整数 0x12345678 为例,在小端序存储时,内存地址从低到高依次存放的字节是 0x780x560x340x12

22、正则表达式

https://blog.youkuaiyun.com/lercent/article/details/106804440

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值