相交链表

总会相等的,要么在相交节点,要么在

public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        ListNode curA = headA;
        ListNode curB = headB;
        int count = 0;
        while (curA != curB){
            //这里为什么可以两个都为null从而退出呢?这是因为这里为null的逻辑啊,他们其实还有一个null节点
            curA = curA == null ? headB:curA.next;
            curB = curB == null ? headA:curB.next;
        }
        return curA;
    }
}

反转链表

class Solution {
    public ListNode reverseList(ListNode head) {
        ListNode pre = null;
        ListNode cur = head;
        while (cur != null){
            ListNode tmp = cur.next;
            cur.next = pre;
            pre = cur;
            cur = tmp;
        }
        return pre;
    }
}

回文链表

拿到链表的解法(这里用linkedlist会超时)

class Solution {
    public boolean isPalindrome(ListNode head) {
        ArrayList<Integer> list = new ArrayList<>();
        ListNode cur = head;
        while (cur != null){
            list.add(cur.val);
            cur = cur.next;
        }
        int left = 0;
        int right = list.size()-1;
        while (left < right){
            if(list.get(left) != list.get(right))return false;
            left++;
            right--;
        }
        return true;
    }
}

空间为O(1)的解法

class Solution {
    public boolean isPalindrome(ListNode head) {
        ListNode index = middle(head);
        ListNode head1 = reverse(index);
        ListNode cur = head;
        ListNode cur1 = head1;
        while (cur != index){
            if(cur.val != cur1.val)return false;
            cur = cur.next;
            cur1 = cur1.next;
        }
        return true;

    }
    public ListNode middle(ListNode head){
        ListNode fast = head;
        ListNode slow = head;
        while (fast != null && fast.next != null){
            slow = slow.next;
            fast = fast.next.next;
        }
        return slow;
    }
    public ListNode reverse(ListNode head){
        ListNode pre = null;
        ListNode cur = head;
        while (cur != null){
            ListNode tmp = cur.next;
            cur.next = pre;
            pre = cur;
            cur = tmp;
        }
        return pre;
    }

}

环形链表

public class Solution {
    public boolean hasCycle(ListNode head) {
        ListNode slow = head;
        ListNode fast = head;
        while (fast != null && fast.next != null){
            fast = fast.next.next;
            slow = slow.next;
            if(fast == slow)return true;
        }
        return false;

    }
}

环形链表Ⅱ

public class Solution {
    public ListNode detectCycle(ListNode head) {
        ListNode fast = head;
        ListNode slow = head;
        while (fast != null && fast.next != null){
            fast = fast.next.next;
            slow = slow.next;
            if(fast == slow){
                ListNode res = head;
                while (res != slow){
                    res = res.next;
                    slow = slow.next;
                }
                return res;
            }
        }
        return null;
    }
}

拼接两个有序链表

class Solution {
    public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
        ListNode cur1 = list1;
        ListNode cur2 = list2;
        ListNode res = new ListNode();
        ListNode cur3 = res;
        while (cur1 != null && cur2 != null){
            if(cur1.val <= cur2.val){
                cur3.next = cur1;
                cur1 = cur1.next;
            }else{
                cur3.next = cur2;
                cur2 = cur2.next;
            }
            cur3 = cur3.next;
        }
        if(cur1 == null){
            cur3.next = cur2;
        }else {
            cur3.next = cur1;
        }
        return res.next;
    }
}

两数相加

会超过int的范围

class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode dummy = new ListNode();
        ListNode cur = dummy;
        int carry = 0;
        //当l1,l2都为空,并且没有进位时,就是结束了。
        while (l1 != null || l2 != null || carry != 0){
            //有值就按值来,没有就按0来
            int val1 = l1 != null ? l1.val : 0;
            int val2 = l2 != null ? l2.val : 0;

            //计算当前位置上的数
            int sum = val1+val2+carry;
            //看下一个进位是多少
            carry = sum/10;
            //确定该节点上的数
            cur.next = new ListNode(sum%10);
            //遍历
            cur = cur.next;
            if(l1 != null) l1 = l1.next;
            if(l2 != null) l2 = l2.next;
        }
        return dummy.next;
    }
}

删除链表的倒数第n个节点

class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode dummy = new ListNode(0,head);
        ListNode front = dummy;
        for(int i = 0;i <= n;i++){
            front = front.next;
        }
        ListNode behind = dummy;
        while (front != null){
            front = front.next;
            behind = behind.next;
        }
        behind.next = behind.next.next;
        return dummy.next;
        
    }
}

两两交换链表的节点

class Solution {
    public ListNode swapPairs(ListNode head) {
        ListNode dummy = new ListNode();
        dummy.next = head;
        ListNode node1 = dummy;
        while (node1.next != null && node1.next.next != null){
            ListNode node2 = node1.next;
            ListNode node3 = node2.next;
            ListNode node4 = node3.next;
            node1.next = node3;
            node3.next = node2;
            node2.next = node4;
            node1 = node2;
        }
        return dummy.next;
    }
}

k个一组翻转链表

class Solution {
    public ListNode reverseKGroup(ListNode head, int k) {
        ListNode dummy = new ListNode(0,head);

        ListNode count = head;
        int sum = 0;
        while (count != null){
            sum++;
            count = count.next;
        }

        ListNode p0 = dummy;
        ListNode pre = null;
        ListNode cur = head;
        while (sum >= k){
            sum -= k;
            for(int i = 0;i < k;i++){
                ListNode tmp = cur.next;
                cur.next = pre;
                pre = cur;
                cur = tmp;
            }
            ListNode tmp1 = p0.next;
            p0.next = pre;
            tmp1.next = cur;
            p0 = tmp1;

        }
        return dummy.next;
    }
}

随机链表的复制

class Solution {
    public Node copyRandomList(Node head) {
        if(head == null) return null;
        Node cur = head;
        HashMap<Node,Node> hashMap = new HashMap<>();
        while(cur != null){
            hashMap.put(cur,new Node(cur.val));
            cur = cur.next;
        }
        cur = head;
        while(cur != null){
            hashMap.get(cur).next = hashMap.get(cur.next);
            hashMap.get(cur).random = hashMap.get(cur.random);
            cur = cur.next;
        }
        return hashMap.get(head);
    }
}

排序链表

class Solution {
    public ListNode sortList(ListNode head) {
        //没有节点和节点为1都不用排序,直接返回
        if(head == null || head.next == null){
            return head;
        }
        //找到中间节点
        ListNode head2 = middle(head);
        //这里会一层层递归下去,直到变成点
        head = sortList(head);
        head2 = sortList(head2);
        //然后合并
        return merge(head,head2);

    }
    //这里不仅仅只找到中间节点
    public ListNode middle(ListNode head){
        ListNode pre = head;
        ListNode slow = head;
        ListNode fast = head;
        while (fast != null && fast.next != null){
            pre = slow;
            slow = slow.next;
            fast = fast.next.next;
        }
        pre.next = null;
        return slow;
    }
    public ListNode merge(ListNode list1,ListNode list2){
        ListNode dummy = new ListNode();
        ListNode cur = dummy;
        while (list1 != null && list2 != null){
            if(list1.val < list2.val){
                cur.next = list1;
                list1 = list1.next;
            }else {
                cur.next = list2;
                list2 = list2.next;
            }
            cur = cur.next;
        }
        cur.next = list1 != null ? list1:list2;
        return dummy.next;
    }
}

合并K个升序链表

class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
        int m = lists.length;
        if(m == 0){
            return null;
        }
        for (int step = 1;step < m;step *= 2){
            for(int i = 0;i < m-step;i += step*2){
                lists[i] = merge(lists[i],lists[i+step]);
            }
        }
        return lists[0];
    }
    public ListNode merge(ListNode list1,ListNode list2){
        ListNode dummy = new ListNode();
        ListNode cur = dummy;
        while (list1 != null && list2 != null){
            if(list1.val < list2.val){
                cur.next = list1;
                list1 = list1.next;
            }else {
                cur.next = list2;
                list2 = list2.next;
            }
            cur = cur.next;
        }
        cur.next = list1 != null ? list1:list2;
        return dummy.next;
    }
}

LRU

class LRUCache {
    public static class Node {
        int key;
        int value;
        Node pre;
        Node next;
        public Node(int K, int V) {
            this.key = K;
            this.value = V;
        }
    }

    private HashMap<Integer, Node> keyToValue;
    private final Node dummy; // 虚拟头尾节点
    private final int capacity;

    public LRUCache(int capacity) {
        this.capacity = capacity;
        this.keyToValue = new HashMap<>(capacity);
        this.dummy = new Node(0, 0);
        dummy.next = dummy;
        dummy.pre = dummy;
    }

    public int get(int key) {
        Node node = getNode(key);
        return node == null ? -1 : node.value;
    }

    public void put(int key, int value) {
        if (keyToValue.containsKey(key)) {
            Node node = getNode(key);
            node.value = value;
        } else {
            Node node = new Node(key, value);
            keyToValue.put(key, node);
            putFront(node);
            // 如果超过容量,移除最久未使用的节点
            if (keyToValue.size() > capacity) {
                Node lastNode = dummy.pre;
                remove(lastNode);
                keyToValue.remove(lastNode.key); // 必须从 HashMap 中删除!
            }
        }
    }

    private Node getNode(int key) {
        if (!keyToValue.containsKey(key)) {
            return null;
        }
        Node node = keyToValue.get(key);
        remove(node); // 先从链表中移除
        putFront(node); // 再放到链表头部
        return node;
    }

    private void remove(Node node) {
        Node pre = node.pre;
        Node next = node.next;
        pre.next = next;
        next.pre = pre;
    }

    private void putFront(Node node) {
        Node oldHead = dummy.next;
        dummy.next = node;
        node.pre = dummy;
        node.next = oldHead;
        oldHead.pre = node;
    }
}
class LRUCache {
    class Node{
        Node pre;
        Node next;
        int val;
        int key;
        public Node(int K,int V){
            key = K;
            val = V;
        }
    }

    HashMap<Integer,Node> keyToValue;
    private int capacity;
    private Node dummy = new Node(0,0);

    public LRUCache(int capacity) {
        keyToValue = new HashMap<>(capacity);
        this.capacity = capacity;
        dummy.pre = dummy;
        dummy.next = dummy;
    }

    public int get(int key) {
        Node node = getNode(key);
        return node != null ? node.val:-1;
    }

    public void put(int key, int value) {
        if(keyToValue.containsKey(key)){
            Node node = getNode(key);
            node.val = value;
        }else {
            Node node = new Node(key, value);
            keyToValue.put(key,node);
            putFront(node);
            if(keyToValue.size() > capacity){
                Node lastNode = dummy.pre;
                remove(lastNode);
                keyToValue.remove(lastNode.key);
            }
        }
    }

    public Node getNode(int key){
        if(keyToValue.containsKey(key)){
            Node value = keyToValue.get(key);
            remove(value);
            putFront(value);
            return value;
        }
        return null;
    }
    public void remove(Node value){
        Node pre = value.pre;
        Node next = value.next;
        pre.next = next;
        next.pre = pre;
    }
    public void putFront(Node value){
        Node tmp = dummy.next;
        dummy.next = value;
        value.pre = dummy;
        value.next = tmp;
        tmp.pre = value;
    }
}

比较是偷走幸福的小偷