数据结构相关
BitMap
思路:
- 构造函数:取商作为长度,如果有余,则长度+1
- set和get思路都是先取参数在bitmap中的index和offset,注意转化为int,然后进行相应的操作。
数据范围从0开始
private long length;
private static int[] bitsMap;
//构造函数中传入数据中的最大值
public BitMap(long length) {
this.length = length;
// 根据长度算出,所需数组大小
// 即length 除以 32 的商,如果不能整除的话,长度再加1
bitsMap = new int[(int) (length >> 5) + ((length & 31) > 0 ? 1 : 0)];
}
public void setBit(long index) {
// 求出该index所在bitMap的下标
int belowIndex = (int) (index >> 5);
// 求出该值的偏移量(求余)
int offset = (int) (index & 31);
int inData = bitsMap[belowIndex];
// 0x01 为十六进制中的1,向左移动offset个位置后得出只有那个位置a为1,其他为0的二进制
// 这个二进制数与inData进行"或"运算,即把inData的二进制形式中a位置的数变为1,
bitsMap[belowIndex] = inData | (0x01 << offset);
}
public int getBit(long index) {
int intData = bitsMap[(int) (index >> 5)];
int offset = (int) (index & 31);
// 向右移动offset,与0x01进行"与"运算,即判断offset那个位置的数是否与1相同,即该数字存在,从而返回1
return intData >> offset & 0x01;
}
public static void main(String[] args) {
BitMap bitMap = new BitMap(32);
bitMap.setBit(0);
System.out.println(bitMap.getBit(0));
System.out.println(bitMap.getBit(31)); // 32就超范围了。
// 结果为1,0 表示存在和不存在
}
最小栈
思路:
- 新建两个栈
- push和pop中,s1照常执行。s2判断其顶部元素是否大于等于x,如果是,做相应操作。在push中,如果s2为空,可以直接push。
// push
s1.push(x);
/** 注意 s2.peek() >= x 中的大于等于 */
if (s2.isEmpty() || s2.peek() >= x) s2.push(x);
// pop
int x = s1.pop();
if (s2.peek() == x) s2.pop();
// top
return s1.peek();
// getMin
return s2.peek();
AllOne
// 记录key和key的计数
private Map<String, Integer> map;
// 记录各层所包含的key
private List<Set<String>> list;
// inc 和 dec:先判断key是否存在,然后取key,list中删除,更新计数以及在map和list中的值和层
// getMaxKey:从后往前遍历list,只要set不为空,就返回set.iterator().next()
// getMinKey:从前往后遍历....
// 遍历完都没有就返回 ""
LRU
// capacity、head、tail、map
// 构造器:实力化map、head、tail连接好两个节点
public int get(int key) {
Node node = map.get(key);
if (node == null) return -1;
moveToHead(node);
return node.value;
}
private void moveToHead(Node node) {
removeNode(node);
addNode(node);
}
private void removeNode(Node node) {
node.pre.next = node.next;
node.next.pre = node.pre;
}
private void addNode(Node node) {
node.pre = head;
node.next = head.next;
head.next.pre = node;
head.next = node;
}
public void put(int key, int value) {
Node node = map.get(key);
if (node == null) {
Node newNode = new Node();
newNode.key = key;
newNode.value = value;
map.put(key, newNode);
addNode(newNode);
if (map.size() > capacity) {
Node tail = popTail();
map.remove(tail.key);
}
} else {
node.value = value;
moveToHead(node);
}
}
private Node popTail() {
Node node = tail.pre;
removeNode(node);
return node;
}
两个栈实现一个队列
思路:
- 新建输入和输出栈
- push就push到inputStack,pop就先把inputStack中的元素放到outputStack后再从outputStack中pop
- peek同样要执行shiftStack,返回时检查outputStack是否为空,是返回0
- shiftStack:如果outputStack为空,就不断把inputStack中的元素放到outputStack中
- empty的判断是inputStack和outputStack同时为空