乐趣区

关于java:java算法易筋经常见javaAPI使用技巧

摘要:算法练习的实质也在于锤炼编程思维,强化程序员的内力。因而给本人前面会继续更新的算法技巧内容简称算法易筋经。

本文分享自华为云社区《<java 算法易筋经 > 之常见 java-API 应用》,原文作者:breakDraw。

易筋经源于我国现代西医导引术, 具备健壮体格、预防疾病的成果, 长期以来在佛家及民间习武人士之间广为流传。算法练习的实质也在于锤炼编程思维,强化程序员的内力。因而给本人前面会继续更新的算法技巧内容简称算法易筋经。

无论你应用什么语言开始训练算法,总是得把握根本的。我这边只以 java 举例,其余语言相似。以 leetcode 类型的平台为主。

java 数组和 list 互转

有时候给定的输出是个数组,两头过程咱们想转成 list 并应用 list 的一些 api。然而这没那么简略。

请关上本人的编译器,而后看下上面几个问题是否不必 for 循环写胜利。(用 for 循环也是对的,考试时如果遗记了,就抉择能用的办法)

  • 请把字符串数组转 list
  • 请把字符串 list 转数组
  • 请把 list<Integer> 转 int[]
  • 请把 int[]转成 List<Integer>

就像上面这样,本人造个类,测试一下看是否秒写:

public class ListArrayUtil {
    // 请把字符串数组转 list
    public List<String> arrToListStr(String[] arr) {return null;}

    // 请把字符串 list 转数组
    public String[] listToArrStr(List<String> list) {return null;}

    // 请把 list 数组转成 int[]
    public List<Integer> arrToListInt (List<Integer> num) {return null;}

    // 请把 int[] 数组转成 list
    public List<Integer> arrToListInt (int[] num) {return null;}
}

有些人可能会误以为 int[]和 Integer[]是能够主动转的,而后对于数组而言,编译器无奈用辨认,会报错。因而如果波及这种根底类型的数组列表转换,请记住 要么马上应用 stream,要么间接 for 循环写一下,不要卡在这个编译谬误这钻研半天。

我的答案:

public class ListArrayUtil {
    // 请把字符串数组转 list
    public List<String> arrToListStr(String[] arr) {return Arrays.asList(arr);
    }

    // 请把字符串 list 转数组
    public String[] listToArrStr(List<String> list) {return list.toArray(new String[list.size()]);
    }

    // 请把 list 数组转成 int[]
    public int[] arrToListInt (List<Integer> list) {// 不能够 toArray,int[]和 Integer[]是不同的
        //return list.toArray(new int[list.size()]);
        return list.stream()
                .mapToInt(Integer::valueOf)
                .toArray();}

    // 请把 int[] 数组转成 list
    public List<Integer> arrToListInt (int[] num) {// 不能够 asList,因为 int[]和 Integer[]不同
        // return Arrays.<Integer>asList(num);
        return Arrays
                .stream(num)
                .boxed()
                .collect(Collectors.toList());
    }
}

list 和数组的初始化

初始化可没那么简略,尤其是波及返回 List[]作为后果时,总是有人会遗记要先初始化数组里的每个 list 能力应用。请实现以下内容:

  • 初始化 list<Integer> 为 5 个 1
  • 初始化 int[]为 5 个 1
  • 初始化 1 个蕴含 5 个 list 的 lis[]数组,并且外面的 list 曾经初始化实现

正确答案如下:

public class ListUtil {

    // 初始化 list 为 5 个 1
    public static List<Integer> fillList() {List<Integer> list = Collections.nCopies(5,1);
        System.out.println(list);
        return list;
    }

    // 初始化 arr 为 5 个 1
    public static int[] fillArr() {int[] arr = new int[5];
        Arrays.fill(arr, 1);
        return arr;
    }

    // 返回 1 个 list 数组,并且外面的 list 曾经初始化实现
    public static List[] fillListArray() {List[] lists = new List[5];
        IntStream.rangeClosed(0, 4).boxed()
                .forEach(i->lists[i] = new ArrayList());
        return lists;
    }
}

排序

对于如何疾速对 list 和数组排序,在 IDEA 本人解答以下问题:

  • Arrays 和 List 如何对 int[]数组做倒序排序
    Arrays.sort()
    Collections.sort()
  • 对于一个新对象,怎么做自定义排序?
    如下。定义一个 comparable
public class Student implements Comparable<Student> {
    private  int stuId;
    private String stuName;
    private int score;
    @Override
    public int compareTo(Student o) {return stuId-o.stuId;}
}

参考题目:https://leetcode-cn.com/probl…

map 相干

  • 如果 map 里的 value 是个 list,每次往某个 key 里的 list 放数据时,必须要先初始化 list,怎么缩小初始化代码?

答案:
应用 getOrDefault:
map.getOrDefault(key, new ArrayList<>()).add(xxx)
图后果那边还蛮罕用的

不做反复的 put

if (!map.containsKey(key)) {map.put(key, value);
}

能够优化成
map.putIfAbsent(key, value)
字面意思:absent 指不存在,那么就是不存在的时候,把 value 放入,如果存在,则间接返回原 value 值。

map 中的值做更新

例如每次对 key 中的值加 1
有两种形式:

map.put(key, map.getOrDefault(key, 0)+1);
map.compute(key, (k,v)->(v==null?1:v+1));

在一个比较复杂的状况下,compute 比拟有用。

computeIfAbsent(key, (k,v)->f(k,v))只在 key 不存在的时候,才计算这个 labmda 式子。如果存在的话,就不计算了,间接返回旧值。

computeIfPresent(key, (k,v)->f(k,v))只有存在才会更新,不存在就不更新。

常见队列用法

  • 一般队列:
  • 优先队列 priorityQueue:
    可能保障出队的永远是依照你设定的最大或者最小的元素。
    很有用。

用 labma 写外部比拟式子,防止遗记接口怎么写
PriorityQueue<int[]> queue = new PriorityQueue<>((a, b) -> a[1] – b[1]);
a[1] – b[1] 是小顶堆
a[1]-b[1] >0,则替换。

如何记忆?
堆更新的时候,都是从上往下更新的,让
那么 a 是下面的点,b 是上面的点(儿子节点)
当返回大于 0 时,替换 a 和 b。

这样就好了解了
大顶堆:a-b<0 时,须要替换,即父亲比儿子小,所以须要替换
小丁堆:a-b>0, 须要替换,即父亲比儿子大,得换,让父亲是小顶。

  • 优先队列延时删除
    当优先队列中某个元素会被删除,然而不在堆顶时,应用提早删除,直到他走到堆顶才会清理。
    因而这时候要应用额定的数量 realCount 来统计队列理论数量,并应用特定的删除标记位(勿用会烦扰到队列 compare 办法的形式去设定删除标记位)

繁难二分查找

  • 在一个 list 中找到最靠近 x 且大于等于 x 值的元素

不想手写二分的话用这个办法:

  • 在一个 list 中找到最靠近 x 且小于等于 x 的元素
    应用 treeMap 搁置数据
    floorKey(key) 能够找到小于等于给定键的最大键
    如果不存在这样的键,则返回 null。

ceilingKey(key) 找到大于等于给定键的最小键
不存在则返回 null

记忆:

ceiling 向上舍入,那就是找 key 的上边。ceiling 有天花板的意思,于是就了解成是向上找。

floor 向下摄入,那就是找 key 的下边。有沉入水下的意思,于是了解成向下。

  • 在 list 中找到最靠近 x 且大于(不蕴含等于)x 的元素

例题:https://leetcode-cn.com/probl…

点击关注,第一工夫理解华为云陈腐技术~

退出移动版