Skip to content

Commit 7507557

Browse files
committed
week02 first commit
1 parent ef09080 commit 7507557

4 files changed

Lines changed: 134 additions & 1 deletion

File tree

Week02/NOTE.md

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,42 @@
1-
学习笔记
1+
学习笔记
2+
###HashMap
3+
####基本概念
4+
它根据键的hashCode值来进行存储,大多数情况下可以直接
5+
定位到它的值。不考虑哈希冲突的情况下,仅需一次定位即
6+
可完成,时间复杂度为O(1)
7+
从结构实现上来看(jdk1.8)HashMap是数组+链表+红黑树
8+
实现的。HashMap有一个非常重要的字段Node[] table,
9+
即哈希桶数组,他是一个Node的数组。Node是HashMap的
10+
一个内部类,实现了Map.Entry接口,本质就是一个映射
11+
(键值对)。如果哈希桶很大,即使差的Hash算法也会比较
12+
分散,如果哈希桶很小,即使好的Hash算法也会出现较多
13+
碰撞,所以就需要在空间成本和时间成本之间进行权衡,
14+
通过Hash算法和扩容因子来进行控制。threshold=length
15+
*Loadfactor,modCount用来记录HashMap内部结构发生
16+
变化的次数,主要用于迭代快速失败。size为HashMap内部
17+
实际存储键值对的数量。length为HashMap中Node[]数组的
18+
长度,HashMap数组的长度length必须是2的n次方。
19+
####具体实现
20+
#####hash算法本质上就三步:
21+
1. 取Key的hash索引值 h=hashcode(),调用hashcode
22+
2. 高位运算 hash=h^(h>>>16),计算Hash
23+
3. 取模运算 (n-1)&hash,计算下标
24+
#####HashMap的put方法
25+
1. 判断键值对数组table[i]是否为空或null,否则执行
26+
resize()进行扩容
27+
2. 根据键值Key计算hash值得到插入的数组索引i,如果
28+
table[i]==null转向6.如果table[i]不为空转向3
29+
3. 判断table[i]的首个元素是否和key一样,如果相同
30+
直接覆盖value,否则转向4.这里的相同指的是hashCode
31+
和equals
32+
4. 判断table[i]是否为treeNode,即table[i]是否为
33+
红黑树,如果是红黑树直接插入键值对,否则转向5
34+
5. 遍历table[i],判断链表长度是否为8,大于8的话
35+
将链表转化为红黑树,在红黑树中执行插入操作,否则
36+
进行链表的插入操作,遍历过程中若发现key已经存在直
37+
接覆盖value即可
38+
6. 插入成功后,判断实际存在的键值对数量size是否超
39+
过了最大容量threshold,如果超过,则进行扩容
40+
#####扩容机制
41+
扩容就是重新计算容量,方法是使用一个新的数组代替已
42+
有的较小的数组。

Week02/com/mypractice/Node.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.mypractice;
2+
3+
import java.util.List;
4+
import java.util.Vector;
5+
/**
6+
* N叉树的数据结构
7+
* */
8+
public class Node {
9+
10+
public int val;
11+
12+
List<Node> children;
13+
14+
public Node() {
15+
16+
}
17+
18+
public Node(int _val) {
19+
this.val=_val;
20+
}
21+
public Node(int _val , List<Node> children) {
22+
this.val=_val;
23+
this.children=children;
24+
}
25+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.mypractice;
2+
3+
4+
import java.util.Collections;
5+
import java.util.LinkedList;
6+
import java.util.List;
7+
8+
public class PreOrder {
9+
public List<Integer> preOrder(Node root) {
10+
LinkedList<Node> stack=new LinkedList<>();
11+
LinkedList<Integer> output=new LinkedList<>();
12+
if (root == null) {
13+
return output;
14+
}
15+
stack.add(root);
16+
while (!stack.isEmpty()) {
17+
Node node=stack.pollLast();
18+
output.add(node.val);
19+
Collections.reverse(node.children);
20+
for (Node item : node.children) {
21+
stack.add(item);
22+
}
23+
}
24+
25+
return output;
26+
}
27+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package com.mypractice;
2+
3+
import java.util.*;
4+
5+
public class TopKFrequent {
6+
public int[] topKFrequent(int[] nums, int k) {
7+
8+
//将数字作为key,数字出现的次数作为value,放入hashmap中
9+
HashMap<Integer,Integer> count=new HashMap<>();
10+
for (int n : nums) {
11+
count.put(n,count.getOrDefault(n,0)+1);
12+
}
13+
//构造大根堆
14+
PriorityQueue<Integer> bigheap = new PriorityQueue<>(Comparator.comparingInt(count::get));
15+
16+
//将大根堆的中排前k个的元素保留,其他元素出队
17+
for (int n : count.keySet()) {
18+
bigheap.add(n);
19+
if (bigheap.size() > k) {
20+
bigheap.poll();
21+
}
22+
}
23+
24+
//将结果集存入目标的数组中
25+
int[] result = new int[k];
26+
for (int i = 0; i < k; i++) {
27+
result[i]=bigheap.poll();
28+
}
29+
return result;
30+
}
31+
32+
public static void main(String[] args) {
33+
TopKFrequent topKFrequent =new TopKFrequent();
34+
int[] nums=new int[]{1,2,1,45,6,7,8};
35+
int k =2;
36+
int[] result = topKFrequent.topKFrequent(nums, k);
37+
System.out.println(Arrays.toString(result));
38+
}
39+
40+
}

0 commit comments

Comments
 (0)