• LeetCode----Linked List


    Swap Nodes in Pairs
    思路:需要构造一个头指针,指向链表。一次比较两个指针,将其翻转,临界条件是pre != null(链表长度为偶数) && pre.next != null(链表长度为奇数),然后更新头指针和pre

    public ListNode swapPairs(ListNode head) {
        if(head == null) return null;
        ListNode newNode = new ListNode(0);
        ListNode node = newNode;
        node.next = head;
        ListNode ptr = head;
        while(ptr != null && ptr.next != null){
            node.next = ptr.next;
            ptr.next = ptr.next.next;
            node.next.next = ptr;
            node = node.next.next;
            ptr = ptr.next;
        }
        return newNode.next;
    }
    

    Insertion Sort List
    思路:构造一个头指针node,指向结果链表。每次取出head和结果链表中的节点val进行比较,知道找到应该插入的位置,插入,然后重置node和head

    public ListNode insertionSortList(ListNode head) {
        if(head == null) return null;
        ListNode node = new ListNode(0);
        while(head != null){
            ListNode pre = node;
            while(pre.next != null && pre.next.val <= head.val){
                pre = pre.next;
            }
            ListNode temp = head.next;
            head.next = pre.next;
            pre.next = head;
            head = temp;
        }
        return node.next;
    }
    

    Odd Even Linked List
    思路:依次取出奇数位节点和偶数位节点,然后将奇数尾和偶数头连接起来

    public ListNode oddEvenList(ListNode head) {
        if(head == null || head.next == null) return head;
        ListNode odd = head;
        ListNode even = head.next;
        ListNode temp = even;
        while(even != null && even.next != null){
            odd.next = even.next;
            odd = odd.next;
            even.next = odd.next;
            even = even.next;
        }
        odd.next = temp;
        return head;
    }
    

    Remove Duplicates from Sorted List II
    思路:构造一个头结点指向链表,后面利用双指针判断val是否一致,若不一致则三个指针同时后移,若一直则尾指针后移直到不一致,利用头指针跳过所有重复的节点。

    public ListNode deleteDuplicates(ListNode head) {
        if(head == null || head.next == null) return head;
        ListNode ptr = new ListNode(0);
        ptr.next = head;
        ListNode copy = ptr;
        ListNode pre = head;
        ListNode pos = head.next;
        while(pos != null){
            if(pos.val != pre.val){
                ptr = ptr.next;
                pre = pre.next;
                pos = pos.next;
            }
            else{
                while(pos != null && pos.val == pre.val){
                    pos = pos.next;
                }
                ptr.next = pos;
                if(pos != null){
                    pre = pos;
                    pos = pos.next;
                }
            }
        }
        //ptr.next = null;
        return copy.next;
    }
    

    Merge k Sorted Lists
    思路:利用归并的思想,依次将链表的列表从中间分开,然后依次合并两个已排好序的链表

    public ListNode mergeKLists(ListNode[] lists) {
        int len = lists.length;
        if(len == 0) return null;
        return helper(lists,0,len - 1);
    }
    
    public ListNode helper(ListNode[] lists,int l,int r){
        if(l < r){
            int m = l + (r - l) / 2;
            return merge(helper(lists,l,m),helper(lists,m + 1,r));
        }
        return lists[l];
    }
    
    public ListNode merge(ListNode l1,ListNode l2){
        if(l1 == null) return l2;
        if(l2 == null) return l1;
        if(l1.val < l2.val){
            l1.next = merge(l1.next,l2);
            return l1;
        }
        else{
            l2.next = merge(l1,l2.next);
            return l2;
        }
    }
    

    类似的:Sort List,也是归并的思想

    Reverse Nodes in k-Group
    思路:构造一个头指针指向链表,依次往后当长度等于k时,则翻转链表,这个过程注意需要保存要翻转链表的头结点

    public ListNode reverseKGroup(ListNode head, int k) {
        ListNode ptr = new ListNode(0);
        ptr.next = head;
        ListNode ptr1 = ptr;
        ListNode curNode = head;
        int cnt = 0;
        while(curNode != null){
            ListNode left = head;
            cnt++;
            if(cnt == k){
                ListNode tail = curNode.next;
                curNode.next = null;
                ListNode leftCopy = left;
                reverse(ptr1,left,curNode);
                leftCopy.next = tail;
                curNode = tail;
                head = curNode;
                ptr1 = leftCopy;
                cnt = 0;
                continue;
            }
            curNode = curNode.next;
        }
        return ptr.next;
    }
    
    public void reverse(ListNode ptr1,ListNode left,ListNode right){
        ListNode p = null;
        ListNode q = left;
        while(left != right){
            left = left.next;
            q.next = p;
            p = q;
            q = left;
        }
        left.next = p;
        ptr1.next = left;
    }
    

    141 双指针,一个快,一个慢,若过程中两指针相同则有环
    19/61 双指针,相隔n
    21 递归
    160 得到两个链表的长度,重置长链表起点使之和短链表一致直到同时达到连接点
    83/203 双指针
    206 翻转指针
    92 找到要翻转指针的范围,翻转
    2/445 首先判断两链表长度,将长的那个作为被加数,即最终一定是加数先置为null,然后一位位相加,注意进位,然后判断是否多余的位上val都是9的情况,最后判断是否需要增加尾指针的情况;445比2多了一个翻转操作
    86 构造两个头结点,分别表示不小于x的链表和小于x的链表,依次构造完以后拼接起来

    常用的小模块和方法:

    1. 翻转链表
    2. 快慢指针得到链表中点
    3. 构造一个节点指向头结点

    练习:
    Palindrome Linked List:找到中点、翻转指针、依次比较
    Delete Node in a Linked List:只能从要删除节点入手,则依次用后节点的val覆盖前节点的val
    Reorder List:找到中点、翻转指针、依次连接
    Linked List Cycle II:快慢指针找到相遇的位置,然后一个从head位置走,一个从相遇位置走,在环节点处相遇(注意没环的情况)
    Convert Sorted List to Binary Search Tree:快慢指针找中点即头结点,递归建树

    链表需注意:判头判尾是否为空、写到.next .val判断当前指针是否为空

  • 相关阅读:
    笔记-归并排序
    Repeated Substring Pattern
    Assign Cookies
    Number of Boomerangs
    Paint Fence
    Path Sum III
    Valid Word Square
    Sum of Two Integers
    Find All Numbers Disappeared in an Array
    First Unique Character in a String
  • 原文地址:https://www.cnblogs.com/LeonNew/p/6062252.html
Copyright © 2020-2023  润新知