3.两数相加
时间复杂度和空间复杂度均为O(max(m,n)), m,n 为两个链表的长度;
class Solution{ public ListNode addTwoNumbers(ListNode l1, ListNode l2){ ListNode head = null, tail = null; int carry = 0; while(l1 != null || l2 != null){ int n1 = l1 != null ? l1.val:0; int n2 = l2 != null ? l2.val:0; int sum = n1 + n2 + carry; if(head == null){ head = tail = new ListNode(sum % 10); }else{ tail.next = new ListNode(sum % 10); tail = tail.next; } carry = sum / 10; if(l1 != null){ l1 = l1.next; } if(l2 != null){ l2 = l2.next; } } if(carry > 0){ tail.next = new ListNode(carry); } return head; } }
4.LRU缓存机制:
哈希表辅以双向链表实现维护缓存中所有的键值对,基本操作是:先使用哈希表进行定位,找出缓存项在双向链表中的位置,将其移动到双向链表的头部,即可在O(1)时间中实现put或get操作,时间复杂度对于put或get操作均为O(1),空间复杂度为O(capacity);
class LRUCache { private HashMap<Integer, Node> map; private DoubleList cache; private int cap; public LRUCache(int capacity){ this.cap = capacity; map = new HashMap<>(); cache = new DoubleList(); } public int get(int key){ if (!map.containsKey(key)) return -1; int val = map.get(key).val; // 利用 put 方法把该数据提前 put(key, val); return val; } public void put(int key, int val){ // 先把新节点 x 做出来 Node x = new Node(key, val); if (map.containsKey(key)){ // 删除旧的节点,新的插到头部 cache.remove(map.get(key)); cache.addFirst(x); // 更新 map 中对应的数据 map.put(key, x); }else{ if (cap == cache.size()){ // 删除链表最后一个数据 Node last = cache.removeLast(); map.remove(last.key); } // 直接添加到头部 cache.addFirst(x); map.put(key, x); } } }