菜鸡的原地踏步史(◐‿◑)

leetcode启动!(╯‵□′)╯︵┻━┻
尝试改掉想到哪写哪的代码坏习惯

链表
相交链表

public class Solution {
    /**
        a
            c(公共长度)
        b
        所以 链表A的长度 a + c,链表B的长度b + c
        a + b + c = b + c + a
        只要指针a从headA开始走,走完再回到headB
        指针b从headB开始走,走完回到headA
        两个指针相遇的地方一定是链表交点
     */
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        ListNode pA = headA;
        ListNode pB = headB;
        while(pA != pB) {
            pA = (pA == null) ? headB : pA.next;
            pB = (pB == null) ? headA : pB.next;
        }
        return pA;
    }
}

反转链表

class Solution {
    /**
        设置一个null结点pre作为反转后的尾结点
        curr结点一路向后遍历
        因为要改变结点指向,所以需要用temp保存curr下一个结点
        开写~
     */
    public ListNode reverseList(ListNode head) {
        ListNode pre = null;
        ListNode cur = head;
        while(cur != null) {
            ListNode temp = cur.next;
            cur.next = pre;
            pre = cur;
            cur = temp;
        }
        return pre;
    }
}

回文链表

class Solution {
    /**
        反转链表,和旧链表逐个元素比较
        主打一个耗时耗力
     */
    public boolean isPalindrome(ListNode head) {
        ListNode pre = null;
        ListNode cur = head;
        ListNode copy = head;
        ListNode old = new ListNode(head.val);
        ListNode oldList = old;
        while(copy != null) {
            // System.out.println(copy.val);
            copy = copy.next;
            if(copy != null) {
                ListNode temp = new ListNode(copy.val);
                old.next = temp;
                old = old.next;
            }
        }
        old.next = null;
        while(cur != null) {
            ListNode temp = cur.next;
            cur.next = pre;
            pre = cur;
            cur = temp;
        }
        ListNode newList = pre;
        while(newList != null) {
            if(newList.val != oldList.val) {
                return false;
            }
            newList = newList.next;
            oldList = oldList.next;
        }
        return true;
    }
}

环形链表

public class Solution {
    /**
        使用快慢指针
        slow一次走一步,fast一次走两步
        快慢指针一定会在环内相遇,记为meet点
        这个时候slow从head开始走,meet从相遇点开始走,两者一定会在环入口相遇
     */
    public boolean hasCycle(ListNode head) {
        ListNode slow = head;
        ListNode fast = head;
        ListNode connect = null;
        while(fast != null && fast.next != null) {
            slow = slow.next;
            fast = fast.next.next;
            if(slow == fast) {
                connect = slow;
                return true;
            }
        }
        return connect == null ? false : true;
    }
}

环形链表II

public class Solution {
    /**
        原来上一题的判断写成了这一题的找环的入口
        思路一样
        接着上一题找到meet点
        此时只要slow再次从头开始走,meet指针向后走,两者就一定会在环入口处相遇
     */
    public ListNode detectCycle(ListNode head) {
        ListNode slow = head;
        ListNode fast = head;
        while(fast != null && fast.next != null) {
            slow = slow.next;
            fast = fast.next.next;
            if(slow == fast) {
                ListNode meet = slow;
                slow = head;
                while(slow != meet) {
                    slow = slow.next;
                    meet = meet.next;
                }
                return slow;
            }
        }
        return null;
    }
}

合并两个有序链表

class Solution {
    /**
        朴实无华的想法
        新建一个头结点null,进行结点挑选
        list1.val > list2.val ? 好,挑list2的结点来复制
        list1.val <= list2.val ? 好,挑list1的结点来复制

        如果list1或者list2走到头了,就直接选择不空的一连(因为已经排好序了)

        需要注意的是,所有的情况用if-else分好,否则会执行出错
     */
    public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
        ListNode p = new ListNode(-1);
        ListNode res = p;
        while(list1 != null || list2 != null) {
            if(list1 == null) {
                p.next = list2;
                return res.next;
            }
            else if(list2 == null) {
                p.next = list1;
                return res.next;
            }
            else {
                if(list1.val > list2.val) {
                    ListNode temp = new ListNode(list2.val);
                    p.next = temp;
                    p = p.next;
                    list2 = list2.next;
                }
                else {
                    ListNode temp = new ListNode(list1.val);
                    p.next = temp;
                    p = p.next;
                    list1 = list1.next;
                }
            }
            
            
        }
        return res.next;
    }
}

两数相加
(什么破代码又臭又长 (┙>∧<)┙へ┻┻)

import java.math.BigInteger;
class Solution {
    /**
        朴实无华的想法,逆序想到栈道先进后出功能,使用栈保存数据
        时间空间效率你是一点不考虑啊苦路西

        测试用例有超出Long范围的,需要BigInteger
        BigInteger b1 = new BigInteger("2020031920200319");
        BigInteger b2 = new BigInteger("2020031820200318");
        //加法
        BigInteger add = b1.add(b2);
        System.out.println(add);
        //减法
        BigInteger subtract = b1.subtract(b2);
        System.out.println(subtract);
        //乘法
        BigInteger multiply = b1.multiply(b2);
        System.out.println(multiply);
        //除法
        BigInteger divide = b1.divide(b2);
        System.out.println(divide);
     */
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        Stack<Integer> stack = new Stack();
        int count1 = 0;
        ListNode p1 = l1;
        while(p1 != null) {
            stack.push(p1.val);
            p1 = p1.next;
            count1++;
        }
        BigInteger sum1 = new BigInteger("0");
        BigInteger base = BigInteger.TEN;
        while(!stack.isEmpty()) {
            int temp = stack.pop();
            count1--;
            BigInteger tempAsBigInteger = BigInteger.valueOf(temp);
            BigInteger ten = base.pow(count1);
            BigInteger mul = tempAsBigInteger.multiply(ten);
            sum1 = sum1.add(mul);
        }
        int count2 = 0;
        ListNode p2 = l2;
        while(p2 != null) {
            stack.push(p2.val);
            count2++;
            p2 = p2.next;
        }
        BigInteger sum2 = new BigInteger("0");
        while(!stack.isEmpty()) {
            int temp = stack.pop();
            count2--;
            BigInteger tempAsBigInteger = BigInteger.valueOf(temp);
            BigInteger ten = base.pow(count2);
            BigInteger mul = tempAsBigInteger.multiply(ten);
            sum2 = sum2.add(mul);
        }
        System.out.println(sum1);
        System.out.println(sum2);

        BigInteger sum = new BigInteger("0");
        sum = sum1.add(sum2);
        System.out.println(sum);
        ListNode res = new ListNode(0);
        ListNode r = res;
        if((sum.compareTo(BigInteger.ZERO)) == 0) {
            return r;
        }
        while((sum.compareTo(BigInteger.ZERO)) != 0) {
            BigInteger x = sum.mod(base);
            // System.out.println(x);
            int x1 = x.intValue();
            // System.out.println(x1);
            ListNode temp = new ListNode((int)x1);
            res.next = temp;
            res = res.next;
            sum  = sum.divide(base);
        }
        return r.next;
    }
}

删除链表点倒数第N个结点

class Solution {
    /**
        快指针fast先走N布
        然后慢指针slow从头开始,和fast一起走,当fast走到头了,slow在的位置就是要删除的位置
        1 - 2 - 3 - 4 - null
                -
    2   1   0
        -
            -       -
                -        -
                删        
     */
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode p = new ListNode(-1);
        p.next = head;
        ListNode res = p;
        ListNode fast = p;
        ListNode slow = p;
        while(n > 0) {
            n--;
            fast = fast.next;
        }
        while(fast.next != null) {
            slow = slow.next;
            fast = fast.next;
        }
        slow.next = slow.next.next;
        return p.next;
    }
}

两两交换链表结点

class Solution {
    /**
        -1 - 1 - 2 - 3 - 4
             1 保存一下pre
        -1 - 2 - 3 - 4
             3 - 4 保存一下after
        -1 - 2 - 1
        -1 - 2 - 1 - 3 - 4
     */
    public ListNode swapPairs(ListNode head) {
        ListNode p = new ListNode(-1);
        ListNode res = p;
        p.next = head;
        while(p.next != null && p.next.next != null) {
            ListNode pre = p.next;
            p.next = p.next.next;
            ListNode after = p.next.next;
            p.next.next = pre;
            pre.next = after;
            p = pre;
        }
        return res.next;
    }
}

K个一组链表反转

class Solution {
    /**
        只需要想递归最后一次
        null <- 2 <- 1  3 -> 4 -> 5 -> null
        2.next = reverseGroup(., k)
     */
    public ListNode reverseKGroup(ListNode head, int k) {
        if(head == null) {
            return null;
        }
        ListNode a = head;
        ListNode b = head;
        for(int i = 0; i < k; i++) {
            if(b == null) {
                return head;
            }
            b = b.next; // 判断要在指针后移之前啊啊啊啊
        }
        // 一开始用的while k--, 忘了把k从0恢复
        ListNode newHead = reverseKNodes(a, b);
        a.next = reverseKGroup(b, k);
        return newHead;
    }
    public ListNode reverseKNodes(ListNode a, ListNode b) {
        ListNode pre = null;
        ListNode cur = a;
        while(cur != b) {
            ListNode temp = cur.next;
            cur.next = pre;
            pre = cur;
            cur = temp;
        }
        return pre;
    }
}

随机链表的复制

class Solution {
    /**
        感觉和拷贝链表没有什么区别
        多了个random嘛, 用hashmap存
     */
    public Node copyRandomList(Node head) {
        Node h = head;
        HashMap<Node, Node> map = new HashMap<>();
        Node newHead = new Node(-1);
        Node h1 = newHead;
        while(h != null) {
            Node temp = new Node(h.val);
            map.put(h, temp);
            newHead.next = temp;
            newHead = newHead.next;
            h = h.next;
        }
        h = head;
        Node h2 = h1.next;
        while(h != null) {
            h2.random = map.get(h.random);
            h = h.next;
            h2 = h2.next;
        }
        return h1.next;
    }
}

排序链表

class Solution {
    /**
        朴实无华的想法
        用List存链表元素,Collections.sort()进行排序,再新建一个链表
     */
    public ListNode sortList(ListNode head) {
        List<Integer> list = new ArrayList();
        ListNode h = head;
        ListNode sortedList = new ListNode(-1);
        ListNode res = sortedList;
        while(h != null) {
            list.add(h.val);
            h = h.next;
        }
        Collections.sort(list);
        for(int i = 0; i < list.size(); i++) {
            ListNode temp = new ListNode(list.get(i));
            sortedList.next = temp;
            sortedList = sortedList.next;
        }
        return res.next;
    }
}

合并K个有序链表

class Solution {
    /**
        使用最小堆
        注意:lists是一个数组,是用lists.length获取长度
     */
    public ListNode mergeKLists(ListNode[] lists) {
        if(lists.length == 0) {
            return null;
        }
        ListNode p = new ListNode(-1);
        ListNode res = p;
        PriorityQueue<ListNode> pq = new PriorityQueue<>(
            lists.length, (a,b) -> (a.val - b.val)
        );
        for(ListNode head :lists) {
            if(head != null) {
                pq.add(head);
            }
        }
        while(!pq.isEmpty()) {
            ListNode node = pq.poll();
            p.next = node;
            if(node.next != null) {
                pq.add(node.next);
            }
            p = p.next;
        }
        return res.next;
    }
}

LRU缓存

class LRUCache {
    /**
        八股问过,内存淘汰策略,删除存活时间最久的key
        allkesy-lru
     */
    int cap;
    LinkedHashMap<Integer, Integer> cache = new LinkedHashMap<>();
    public LRUCache(int capacity) {
        this.cap = capacity;
    }
    
    public int get(int key) {
        if(!cache.containsKey(key)) {
            return -1;
        }
        makeRecently(key);
        return cache.get(key);
    }
    
    public void put(int key, int val) {
        if(cache.containsKey(key)) {
            cache.put(key, val);
            makeRecently(key);
            return;
        }
        if(cache.size() >= this.cap) {
            int oldestKey = cache.keySet().iterator().next();
            cache.remove(oldestKey);
        }
        cache.put(key, val);
    }
    private void makeRecently(int key) {
        int val = cache.get(key);
        cache.remove(key);
        cache.put(key, val);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值