数据结构相关

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同时为空
原文地址:https://www.cnblogs.com/code2one/p/10100193.html