0
点赞
收藏
分享

微信扫一扫

关于LeetCode上的链表

彭维盛 2022-03-16 阅读 44
链表java

目录

1、将两个单向升序链表合并为一个链表

2、给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。

3、给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点

4、将一个链表数组中的链表按照升序合并

5、两两交换链表中的节点

6、反转链表

7、反转链表的前n个节点

8、只反转从位置m到位置n


总结:

        善于运用递归思想;

        在头节点前设置一个哑结点很多时候会很方便;

 

1、将两个单向升序链表合并为一个链表

class Solution {

    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {

        ListNode prehead = new ListNode(-1);   //预先指针,值随便写

        ListNode prev = prehead;    //当前指针

        while (l1 != null && l2 != null) {

            if (l1.val <= l2.val) {

                prev.next = l1;

                l1 = l1.next;

            } else {

                prev.next = l2;

                l2 = l2.next;

            }

            prev = prev.next;

        }

        // 合并后 l1 和 l2 最多只有一个还未被合并完,我们直接将链表末尾指向未合并完的链表即可

        prev.next = l1 == null ? l2 : l1;

        return prehead.next;

    }

}

2、给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。请你将两个数相加,并以相同形式返回一个表示和的链表。你可以假设除了数字 0 之外,这两个数都不会以 0 开头。

class Solution {

    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {

        ListNode pre = new ListNode(0);  //预先指针

        ListNode cur = pre;    //当前指针

        int carry = 0;   //进位值

        while(l1 != null || l2 != null) {

            int x = l1 == null ? 0 : l1.val;  

            int y = l2 == null ? 0 : l2.val;

            int sum = x + y + carry;

            carry = sum / 10;    //表示进位值

            sum = sum % 10;    //实际存入链表的值

            cur.next = new ListNode(sum);

            cur = cur.next;

            if(l1 != null)

                l1 = l1.next;

            if(l2 != null)

                l2 = l2.next;

        }

        if(carry == 1) {

            cur.next = new ListNode(carry);

        }

        return pre.next;

    }

}

3、给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点

class Solution {

    public ListNode removeNthFromEnd(ListNode head, int n) {

        ListNode dummy = new ListNode(0, head);

        int length = getLength(head);

        ListNode cur = dummy;

        for (int i = 1; i < length - n + 1; ++i) {

            cur = cur.next;

        }

        cur.next = cur.next.next;

        ListNode ans = dummy.next;

        return ans;

    }

    public int getLength(ListNode head) {

        int length = 0;

        while (head != null) {

            ++length;

            head = head.next;

        }

        return length;

    }

}

4、将一个链表数组中的链表按照升序合并

思路:我们可以想到一种最朴素的方法:用一个变量 ans 来维护以及合并的链表,第 i 次循环把第 i 个链表和 ans 合并,答案保存到 ans 中。

class Solution {

    public ListNode mergeKLists(ListNode[] lists) {

        ListNode ans = null;

        for (int i = 0; i < lists.length; ++i) {

            ans = mergeTwoLists(ans, lists[i]);

        }

        return ans;

    }

    public ListNode mergeTwoLists(ListNode a, ListNode b) {

        if (a == null || b == null) {

            return a != null ? a : b;

        }

        ListNode head = new ListNode(0);

        ListNode tail = head, aPtr = a, bPtr = b;

        while (aPtr != null && bPtr != null) {

            if (aPtr.val < bPtr.val) {

                tail.next = aPtr;

                aPtr = aPtr.next;

            } else {

                tail.next = bPtr;

                bPtr = bPtr.next;

            }

            tail = tail.next;

        }

        tail.next = (aPtr != null ? aPtr : bPtr);

        return head.next;

    }

}

5、两两交换链表中的节点(递归)

class Solution {

    public ListNode swapPairs(ListNode head) {

        if (head == null || head.next == null) {

            return head;

        }

        ListNode newHead = head.next;

        head.next = swapPairs(newHead.next);

        newHead.next = head;

        return newHead;

    }

}

6、反转链表(递归)

public ListNode reverseList(ListNode head) {

//递归结束条件

    if (head == null || head.next == null) {

        return head;

    }

    // 调用递推公式反转当前结点之后的所有节点

    // 返回的结果是反转后的链表的头结点

    ListNode newHead = reverseList(head.next);

    head.next.next = head;

    head.next = null;

    return newHead;

}

7、反转链表的前n个节点(递归)

ListNode topNSuccessor = null;

private ListNode reverseTopN(ListNode head, int n) {

    if (n == 1) {

        topNSuccessor = head.next;

        return head;

    }

    ListNode newHead = reverseTopN(head.next, n-1);

    head.next.next = head;

    head.next = topNSuccessor;

    return newHead;

}

8、只反转从位置m到位置n(递归)

public ListNode reverseBetween(ListNode head, int m, int n) {

    if (m == 1) {

        return reverseTopN(head, n);

    }

    ListNode between = reverseBetween(head.next, m-1,n-1);

    head.next = between;

    return head;

}

ListNode topNSuccessor = null;

private ListNode reverseTopN(ListNode head, int n) {

    if (n == 1) {

        topNSuccessor = head.next;

        return head;

    }

    ListNode newHead = reverseTopN(head.next, n-1);

    head.next.next = head;

    head.next = topNSuccessor;

    return newHead;

}

举报

相关推荐

0 条评论