算法涉及的常规方法总结一数据结构

草稿:待整理

1、Arrays和Collections

经常会用到map统计完次数后找到最大或最小的次数

Collections.min(map.values())
Collections.max(map.values())

map也可以这样子找最大最小value,java8的新特性,业务中暂时没用到min或max

Map.Entry<String, Integer> e = map.entrySet().stream().min(Comparator.comparing(e -> e.getValue())).get();

字符串转数组后需要排序或翻转

Collections.sort(list);
Collections.reverse(list);

比较数组是否相等

Arrays.equals
public static boolean equals(Object[] a, Object[] a2) 
最终是遍历比较Object.equals结果

数组转换为stream

Arrays.stream(res).forEach(e-> System.out.println(e));

2、数组

典型遍历

for(int i=0;i<arr.length;i++){
      arr[i];
}
for(char c:string.toCharArray()){
      c;
}
for(int i=0;i<string.length();i++){
     string.charAt(i);
}

数组的复制,可以用System类的arrayCopy方法

public static native void arraycopy(Object src, int srcPos,Object dest, int destPos, int length);

也可以用Arrays类的copyOf,底层调用的也是arrayCopy,这个方法默认了起始位置都是0,copy的长度是两者中较短的

public static int[] copyOf(int[] original, int newLength) {
    int[] copy = new int[newLength];
    System.arraycopy(original, 0, copy, 0,Math.min(original.length, newLength));      
    return copy;
}

数组的元素计数,除了HashMap,还可以这样子....

假设规定数组中的整数值在0-1000
int[] nums = new int[1001];
for (int i : arr1) {
   nums[i]++;
}

 int[] 转 Integer[],List<Integer>

// int[] --->IntStream---> List<Integer>
List<Integer> list = IntStream.of(intArr).boxed().collect(Collectors.toList());
// int[] --->IntStream---> Integer[]
Integer[] integerArr = IntStream.of(intArr).boxed().toArray(Integer[]::new);
// Integer[] --->Stream<Integer>---> int[]
Arrays.stream(integerArr).mapToInt(Integer::valueOf).toArray();

3、ArrayList

List<Integer>转int[]和Integer[]

int[] arr = list.stream().mapToInt(i->i).toArray();
Integer[] arr= list.toArray(new Integer[0]);
List<Integer> list2 = Arrays.asList(integerArr);(Integer[] ------>List<Integer>)

4、Map相关

(1)需要有序的map时,LinkedHashMap和TreeMap都有使用场景,但是有区别

保持插入顺序用LinkedHashMap,保持插入后key按自然顺序排列用TreeMap(也可以自定义Comparator)

这时候就不要强行用HashMap,然后再一通骚操作使用各种手段排一遍了,除非业务需要

搜索"合并表记录"这题

(2)遍历的速度

for (Map.Entry<Integer, Integer> e : map.entrySet()){
    System.out.println(e.getKey() + " " + e.getValue());
}

map.forEach((k, v) -> System.out.println(k + " " + v));

前者比后者遍历用时更短,搜索"合并表记录"这题

以上很容易就超时,虽然都实现了功能,速度区别很大

(3)统计次数的简单写法

map.put(key, map.getOrDefault(key, 0) + 1);
以前经常这样写:
if(map.containsKey(key)){
    map.put(key,map.get(key)+1);
}else{
    map.put(key,1);
}

5、set去重

HashSet

如果去重后还需要排序,则Collections.sort(new ArrayList<Integer>(set))

如果要求去重且"保持原来的顺序"而不是重新排序,LinkedHashSet即可

判断一堆元素是否有重复,可以使用boolean add(Object o),false说明有重复的

6、链表

双指针判断环

(1) 输入的头结点是 NULL的情况,或者整个链表只有一个结点的时候

(2) 链表断裂的考虑

典型遍历和处理逻辑

public class ListNode{
    int val;
    ListNode next;  
ListNode(int x) { val = x; }
}

第一种while最常用:
void traverse(ListNode head){
    ListNode p = head;
    while (p!=null){
        //do
        p = p.next;
    }  
}
第二种少见:
void traverse(ListNode head){
    travaverse(head.next); 
}

7、树

二叉树:

class TreeNode{
    int val;
    TreeNode left;
    TreeNode right;
}
void traverse(TreeNode root){
    root;
    travaverse(root.left); 
    travaverse(root.right); 
    //三者顺序不同引出的pre,in,post遍历方式
}

多叉树:

class TreeNode{
    int val;
    TreeNode[] children;
}
void traverse(TreeNode root){
    root;
    for(TreeNode child:root.children){
        traverse(child);
    }
}
原文地址:https://www.cnblogs.com/yb38156/p/14529795.html