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


    草稿:待整理

    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);
        }
    }
  • 相关阅读:
    八、springboot 简单优雅的通过docker-compose 构建
    【并发编程】ThreadLocal其实很简单
    计算机网络
    相似度
    不同激活函数的区别
    快速排序+归并排序
    xgboost
    c++面试
    PCA算法和SVD
    各种排序算法的时间复杂度和空间复杂度
  • 原文地址:https://www.cnblogs.com/yb38156/p/14529795.html
Copyright © 2020-2023  润新知