学习笔记08_27
算法:
前K个高频单词
class Solution {
public List<String> topKFrequent(String[] words, int k) {
Map<String, Integer> count = new HashMap();
for (String word: words) {
count.put(word, count.getOrDefault(word, 0) + 1);
}
List<String> candidates = new ArrayList(count.keySet());
Collections.sort(candidates, (w1, w2) -> count.get(w1).equals(count.get(w2)) ?
w1.compareTo(w2) : count.get(w2) - count.get(w1));
return candidates.subList(0, k);
}
复杂度分析
public List<String> topKFrequent(String[] words, int k) {
Map<String, Integer> count = new HashMap();
for (String word: words) {
count.put(word, count.getOrDefault(word, 0) + 1);
}
PriorityQueue<String> heap = new PriorityQueue<String>(
(w1, w2) -> count.get(w1).equals(count.get(w2)) ?
w2.compareTo(w1) : count.get(w1) - count.get(w2) );
for (String word: count.keySet()) {
heap.offer(word);
if (heap.size() > k) heap.poll();
}
List<String> ans = new ArrayList();
while (!heap.isEmpty()) ans.add(heap.poll());
Collections.reverse(ans);
return ans;
}
时间复杂度:O(N log{N})。其中 N 是 words 的长度。我们用 O(N) 时间计算每个单词的频率,然后用 O(NlogN) 时间对给定的单词进行排序。
空间复杂度:O(N),用来存放候答案的地方
基础知识
Iterator 和 ListIterator 有什么区别?
相同
都是迭代器,都可以用于迭代Collection集合
都可以顺序向后遍历集合元素
都可以移除底层集合元素
不同
ListIteaator有add方法,可以添加元素到底层集合中,位置在迭代器当前位置之前
ListIterator可以向前遍历,Iterator不能
ListIterator可以通过nextIndex以及preIndex定位索引位置,Iteratoor不能
ListIterator可以通过set方法对元素进行修改
怎么确保一个集合不能被修改?
通过Collections工具类的静态方法unmodifiableXxx对可变集合进行封装
通过Collections的静态方法emptyXxx返回一个空的不可变集合
通过Collections静态方法singletonXxx返回带有特定对象的不可变集合
并行和并发有什么区别?
并行是指能同时处理多个任务的能力,属于计算机硬件处理范畴
并发是指多个任务被计算机交替执行,例如Java的多线程,属于计算机软件的范畴
线程和进程的区别?
所处位置
进程处于操作系统中,是操作系统分配空间与资源的最小单位
线程处于进程中,是进程划分的更小的运行单位
资源分配
进程的资源是由操作系统分配的
线程的资源由进程分配的
内存地址
进程的内存地址是唯一的,由操作系统分配
线程共享父进程的内存地址
崩溃情况
进程崩溃由操作系统协调,大多不会影响其他线程
线程崩溃会导致父进程的崩溃
切换需要资源
进程切换需要较大资源消耗
线程切换比较轻量
栈和堆
储存:自动存储周期 和 动态存储周期
栈中基本类型,自动存储周期 ,帧的大小在编译时期就已经确定,只存在于方法调用过程中,一个栈帧中包含了一个方法调用所需用到的所有数据:包括参数,返回地址,本地变量
引用类型是存在堆区,动态存储周期
在 Queue 中 poll()和 remove()有什么区别?
在队列不为空时,两者的作用都是返回队头元素
在队列为空时,使用poll方法会返回null,使用remove则会抛出NoSuchElementException异常
如何实现数组和 List 之间的转换?
List转Array
调用List成员方法toArray
for循环生成Array
Array转List
调用Arrays类方法asList
for循环生成
BIO、NIO、AIO 有什么区别?
BIO
BIO是同步阻塞性的IO
调用者等待线程处理完返回结果
NIO
同步非阻塞
程序与IO建立通道channel
数据经过channel传输到缓冲区buffer
selector进行轮询channel获取buffer情况
selector通知调用者获取结果
AIO
异步非阻塞
大致过程与NIO一致
在buffer满之后,通过回调将数据返回到调用者
String 类的常用方法
字符类
charAt(int),根据索引找到索引上字符
indexOf,寻找条件在当前字符串上的索引
字符串信息类
length,字串长度
isEmpty,判断字符串是否为空
字符串操作类
trim,删除字符串中前后空格
substring,截取一部分字符串
toUpperCase,将字符串全变成大写
spilt,根据条件切割字符串并返回数组
concat,追加字符串
线程有哪些状态?
新建,就绪,运行,阻塞,死亡五种状态
当调用线程类的start方法时,线程进入就绪状态,等待获得CPU时间片
线程得到CPU时间片时进行运行状态
当调用sleep方法,调用阻塞式I/O,试图获取同步监视器,suspend被调用,等待notify时,进入阻塞状态
当被notify,获取到资源或同步监视器时,进行就绪状态
当run/call方法执行完毕,抛出异常未处理或调用stop方法时,线程死亡
Lambda 表达式(匿名函数)
将代码块赋值给一个java变量;
- 去掉多余的修饰范围, 多余的函数名称,返回类型也可以去除, 这样编译器可以自己获得返回值类型;
- 传入参数的类型,这个也可以删除,编译器可以自己获得
- 只有一行代码的时候可以去除大括号, 然后使用 ->来代替;
Lambda类型都是一个接口, 包含传入值, 实现;
//使用范围:主要用来定义行内执行的方法类型接口
技巧:
Lambda结合FunctionalInterface Lib, forEach, stream(),method reference等新特性可以使代码变的更加简洁!
todo