0
点赞
收藏
分享

微信扫一扫

链表算法 篇一


双指针技巧解题-链表题目

1.合并两个有序链表

链表算法 篇一_链表

package com.algorithm202305.linkedlist;


/**
 * 合并两个有序列表 https://leetcode.cn/problems/merge-two-sorted-lists/
 * 引用虚拟节点和一个指向虚拟节点的引用p 它只是作为一个指针在构建新的链表时使用,并最终帮助确定合并后链表的尾部
 */
public class Demo1 {
    public static class ListNode {
        int val;
        ListNode next;

        ListNode() {
        }

        ListNode(int val) {
            this.val = val;
        }

        ListNode(int val, ListNode next) {
            this.val = val;
            this.next = next;
        }
    }

    public static void main(String[] args) {

        ListNode listNode1 = new ListNode(2);
        ListNode listNode3 = new ListNode(4);
        listNode1.next = listNode3;
        ListNode listNode2 = new ListNode(3);
        ListNode listNode4 = new ListNode(5);
        ListNode listNode5 = new ListNode(4);
        listNode2.next = listNode4;
        listNode4.next = listNode5;
        traverse(mergeTwoLists(listNode1, listNode2));
    }

    public static ListNode mergeTwoLists(ListNode p1, ListNode p2) {
        // 虚拟头结点
        ListNode dummy = new ListNode(-1), p = dummy;//p指针合并链表
        while (p1 != null && p2 != null) {
            // 比较 p1 和 p2 两个指针
            // 将值较小的的节点接到 p 指针
            if (p1.val > p2.val) {
                p.next = p2;
                p2 = p2.next;
            } else {
                p.next = p1;
                p1 = p1.next;
            }
            // p 指针不断前进
            p = p.next;
        }

        if (p1 != null) {
            p.next = p1;
        }

        if (p2 != null) {
            p.next = p2;
        }

        return dummy.next;
    }

    static void traverse(ListNode head) {
        // 递归访问 head.val
        System.out.print(head.val + " ");
        if (head.next != null) {

            traverse(head.next);
        }
    }
}

2.单链表分解

链表算法 篇一_数据机构_02

package com.algorithm202305.linkedlist;

/**
 * 单链表的分解
 * 在合并两个有序链表时让你合二为一,而这里需要分解让你把原链表一分为二。
 * 具体来说,我们可以把原链表分成两个小链表,一个链表中的元素大小都小于 x,另一个链表中的元素都大于等于 x,最后再把这两条链表接到一起,就得到了题目想要的结果。
 */
public class Demo2 {
    public static void main(String[] args) {
        ListNode l1 = new ListNode(1);
        ListNode l2 = new ListNode(4);
        ListNode l3 = new ListNode(3);
        ListNode l4 = new ListNode(2);
        ListNode l5 = new ListNode(5);
        ListNode l6 = new ListNode(2);
        l1.next = l2;
        l2.next = l3;
        l3.next = l4;
        l4.next = l5;
        l5.next = l6;
        traverse(partition(l1,3));

    }
    public static class ListNode {
        int val;
       ListNode next;

        ListNode() {
        }

        ListNode(int val) {
            this.val = val;
        }

        ListNode(int val, ListNode next) {
            this.val = val;
            this.next = next;
        }
    }
    static ListNode partition(ListNode head, int x) {
        //虚拟节点1 存放小于x的节点
        ListNode dummy1 = new ListNode(-1);
        //虚拟节点2 存放大于等于x的节点
        ListNode dummy2 = new ListNode(-1);
        //p1,p2负责生成dummy1和dummy2的结果链表
        ListNode p1 = dummy1,p2 = dummy2;
        ListNode p = head;
        while (p != null){
            if(p.val < x){
                p1.next = p;
                p1 = p1.next;
            }else {
                p2.next = p;
                p2 = p2.next;
            }
            // 断开原链表中的每个节点的 next 指针 //考公
            ListNode temp = p.next;
            p.next = null;
            p = temp;

        }
        p1.next = dummy2.next;
        return dummy1.next;
    }
    static void traverse(ListNode head) {
        // 递归访问 head.val
        System.out.print(head.val + " ");
        if (head.next != null) {

            traverse(head.next);
        }
    }
}

举报

相关推荐

0 条评论