【LeetCode-java】001-300复习【03】链表专题

今天更新的链表相关的题目~

  1. 中等 两数相加 Add Two Numbers
    20.07.13
    思路:一个carry,然后建表。
class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode dummy = new ListNode(0);
        ListNode curr = dummy;
        int carry = 0;

        while(l1 != null || l2 != null || carry != 0){
            int val1 = l1 == null ? 0 : l1.val;
            int val2 = l2 == null ? 0 : l2.val;
            int sum = val1 + val2 + carry;
            carry = sum / 10;

            ListNode sumNode = new ListNode(sum % 10);
            curr.next = sumNode;
            curr = curr.next;

            if(l1 != null) l1 = l1.next;
            if(l2 != null) l2 = l2.next;
        }
        return dummy.next;
    }
}
  1. 简单 合并两个有序链表 Merge Two Sorted Lists
    20.07.13
    思路:之前想的太复杂了。
class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        ListNode dummy = new ListNode(0);
        ListNode curr = dummy;

        while(l1 != null && l2 != null){
            if(l1.val < l2.val) {
                curr.next = l1;
                l1 = l1.next;
            }else{
                curr.next = l2;
                l2 = l2.next;
            }
            curr = curr.next;  
        }

        if(l1 != null){
            curr.next = l1;
        }else{
            curr.next = l2;
        }
          
        return dummy.next;
    }
}
  1. 困难 合并K个有序链表 Merge K Sorted Lists
    20.07.14
    思路:这里是重写了priorityqueue的compare方法,比较有意思。
 class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
        if(lists.length == 0) return null;
        ListNode dummyHead = new ListNode(0);
        ListNode curr = dummyHead;
        PriorityQueue<ListNode> pq = new PriorityQueue<>(new Comparator<ListNode>(){
            @Override
            public int compare(ListNode o1,ListNode o2){
                return o1.val - o2.val;
            }
        });

        for(ListNode list:lists){
            if(list == null) continue;
            pq.add(list);
        }

        while(!pq.isEmpty()){
            ListNode nextNode = pq.poll();
            curr.next = nextNode;
            curr = curr.next;
            if(nextNode.next != null){
                pq.add(nextNode.next);
            }
        }
        return dummyHead.next;
    }
}
  1. 中等 两两交换链表中的节点 Swap Nodes in Pairs
    20.07.13
    思路:也是递归。链表的题想不出来就想递归。
class Solution {
    public ListNode swapPairs(ListNode head) {
        if(head == null || head.next == null) return head;
        ListNode curr = head.next;
        head.next = swapPairs(curr.next);
        curr.next = head;
        return curr;
    }
}
  1. 困难 K个一组翻转链表 Reverse Nodes in K Group
    20.07.13
    思路:这个题的难点在于翻转。这个最好记一下。next = curr.next; curr.next = next.next; next.next = prev.next; prev.next = next; 也不难记,就是一个回环。
class Solution {
    public ListNode reverseKGroup(ListNode head, int k) {
        ListNode dummy = new ListNode(0);
        dummy.next = head;
        ListNode prev = dummy;
        ListNode curr = head;
        ListNode next;
        int length = 0;

        while(head != null){
            length++;
            head = head.next;
        }
        head = dummy.next;

        for(int i=0;i<length/k;i++){
            for(int j=0;j<k-1;j++){
                next = curr.next;
                curr.next = next.next;
                next.next = prev.next;
                prev.next = next;
            }
            prev = curr;
            curr = prev.next;
        }
        return dummy.next;
    }
}
  1. 中等 删除排序链表中的重复元素II Remove Duplicates From Sorted List II
    20.07.13
    思路:为什么这个题用递归好做?因为可能多次出现的是连续的,比如111122223333,这样的话用递归好一些,如同遍历二叉树。
class Solution {
    public ListNode deleteDuplicates(ListNode head) {
        if(head == null || head.next == null) return head;
        ListNode curr = head.next;
        if(head.val == curr.val){
            while(curr != null && head.val == curr.val){
                curr = curr.next;
            }
            head = deleteDuplicates(curr);
        }else{
            head.next = deleteDuplicates(curr);
        }
        return head;
    }
}
  1. 简单 删除排序链表中的重复元素 Remove Duplicates from Sorted List
    20.07.14
    思路:第一眼看成了82题,晕。
class Solution {
    public ListNode deleteDuplicates(ListNode head) {
        if(head == null || head.next == null) return head;
        head.next = deleteDuplicates(head.next);
        if(head.val == head.next.val) head = head.next;
        return head;
    }
}
  1. 中等 反转链表II Reverse Link List II
    20.07.14
    思路:非常简单,做过反转链表的就会写,不过是在后面一块反转罢了。
class Solution {
    public ListNode reverseBetween(ListNode head, int m, int n) {
        ListNode dummy = new ListNode(0);
        dummy.next = head;
        ListNode prev = dummy;
        for(int i=1;i<m;i++){
            prev = prev.next;
        }
        ListNode curr = prev.next;
        for(int i=m;i<n;i++){
            ListNode next = curr.next;
            curr.next = next.next;
            next.next = prev.next;
            prev.next = next;//背下来
        }
        return dummy.next;

    }
}
  1. 中等 复制带随机指针的链表 Copy List With Random Pointer
    20.07.14
    思路:用Map
class Solution {
    public Node copyRandomList(Node head) {
        if(head == null) return head;
        Node node = head;
        Map<Node,Node> map = new HashMap<>();
        while(node != null){
            Node clone = new Node(node.val,null,null);
            map.put(node,clone);
            node = node.next;
        }
        node = head;
        while(node != null){
            map.get(node).next = map.get(node.next);
            map.get(node).random = map.get(node.random);
            node = node.next;
        }
        return map.get(head);
    }
}
  1. 中等 重排链表 Reorder List
    20.07.14
    思路:真TM难。
class Solution {
    public void reorderList(ListNode head) {
        if(head == null || head.next == null) return ;
        ListNode slow = head;
        ListNode fast = head;
        while(fast.next != null && fast.next.next != null){
            fast = fast.next.next;
            slow = slow.next;
        }

        ListNode reverseBegin = slow.next;
        slow.next = null;
        reverseBegin = reverse(reverseBegin);

        ListNode curr = head;
        while(curr != null && reverseBegin != null){
            ListNode curSecond = reverseBegin;
            reverseBegin = reverseBegin.next;
            ListNode nextCur = curr.next;
            curSecond.next = curr.next;
            curr.next = curSecond;
            curr = nextCur;
        }

    }

    public ListNode reverse(ListNode head){
        ListNode p1 = null;
        ListNode p2 = head;
        ListNode p3 = p2;
        while(p2!= null){
            p3 = p2.next;
            p2.next = p1;
            p1 = p2;
            p2 = p3;
        }
        return p1;
    }
}
  1. 中等 对链表进行插入排序 Insertion Sort List
    20.07.15
    思路:比较前驱与现在,之后交换节点。我想画个图在这里。
class Solution {
    public ListNode insertionSortList(ListNode head) {
        ListNode dummy = new ListNode(0);
        ListNode prev;
        dummy.next = head;

        while(head != null && head.next != null){
            if(head.val <= head.next.val){
                head = head.next;continue;
            }
            prev = dummy;
            while(prev.next.val < head.next.val) prev = prev.next;

            ListNode curr = head.next;
            head.next = curr.next;
            curr.next = prev.next;
            prev.next = curr;
        }
        return dummy.next;
    }
}
  1. 中等 排序链表 Sort List
    20.07.15
    思路:
class Solution {
    public ListNode sortList(ListNode head) {
        return merger(head);
    }

    private ListNode merger(ListNode head){
        if(head == null || head.next == null) return head;
        // 找中点
        ListNode slow = head;
        ListNode fast = head.next.next;
        ListNode left;
        ListNode right;

        while(fast != null && fast.next != null){
            slow = slow.next;
            fast = fast.next.next;
        }

        //右边二分
        right = merger(slow.next);
        //中间断开
        slow.next = null;
        //左边二分
        left = merger(head);
        return mergeList(left,right);
    }

    private ListNode mergeList(ListNode left,ListNode right){
        ListNode dummy = new ListNode(-1);
        ListNode p = dummy;
        //这里相当于重新拷贝了一个链表,left和right就是左和右两个子链表
        while(left != null && right != null){
            if(left.val < right.val){
                p.next = left;
                left = left.next;
            }else{
                p.next = right;
                right = right.next;
            }
            p = p.next;
        }
        //一个挂没了就连上另一个
        p.next = left == null ? right : left;
        return dummy.next;
    }
}
  1. 简单 相交链表 Intersection of Two Linked Lists
    20.07.15
    思路:这好像就是那个很浪漫的那个题,对的人会再相逢。
public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        if(headA == null || headB == null) return null;
        ListNode p1 = headA;
        ListNode p2 = headB;
        while(p1 != p2){
            p1 = (p1 == null) ? headB : p1.next;//到头了就走另一个链表
            p2 = (p2 == null) ? headA : p2.next;
        }
        return p1;
    }
}
  1. 简单 移除链表元素 Remove Linked List Elements
    20.07.15
    思路:非常常规的一个题。
class Solution {
    public ListNode removeElements(ListNode head, int val) {
        if(head == null) return head;
        ListNode dummy = new ListNode(0);
        ListNode curr = dummy;//一般curr要从dummy开始,尽量少从head开始
        dummy.next = head;

        while(curr.next != null){
            if(curr.next.val == val){
                curr.next = curr.next.next;//若移除,则不要在这里就curr=curr.next
            }else{
                curr = curr.next;
            }
        }
        return dummy.next;
        
    }
}
  1. 简单 反转链表 Reverse Linked List
    20.07.15
    思路:不用太复杂,这个思路其实是最清楚的。相当于三指针一个一个折回去。
class Solution {
    public ListNode reverseList(ListNode head) {
        ListNode prev = null;
        ListNode curr = head;
        while(curr != null){
            ListNode next = curr.next;
            curr.next = prev;//指针回来
            prev = curr;
            curr = next;//右移
        }
        return prev;
    }
}
  1. 简单 删除链表中的元素 Delete Node in a Linked List
    20.07.15
    思路:这题题目讲的不太好(翻译的不清楚),不用复习了。
class Solution {
    public void deleteNode(ListNode node) {
        node.val = node.next.val;
        node.next = node.next.next;
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_42711949/article/details/107451222