题目:

给定一个链表和一个特定值 x,将链表中所有小于 x 的节点移到大于或等于 x 的节点之前,保持原有相对位置。

引言:

"分隔链表" 是一个关于链表操作的问题。解决这个问题需要对链表的基本操作有一定的理解,同时需要找到一种方法来重新组织链表中的节点。通过解答这个问题,我们可以提升对链表操作的考虑,同时也能拓展对链表处理的能力。

算法思路:

为了实现链表的分隔,我们可以维护两个新的链表,一个链表用来存放小于 x 的节点,另一个链表用来存放大于等于 x 的节点。具体思路如下:

  1. 创建两个链表 lessThanXgreaterThanOrEqualX,分别用于存放小于 x 的节点和大于等于 x 的节点。
  2. 遍历原链表,将小于 x 的节点添加到 lessThanX 链表中,将大于等于 x 的节点添加到 greaterThanOrEqualX 链表中。
  3. lessThanX 链表的尾节点指向 greaterThanOrEqualX 链表的头节点,从而将两个链表连接起来。
  4. 最后,将 greaterThanOrEqualX 链表的尾节点指向 null,防止形成环。

代码实现:

以下是使用 Java 实现的 "分隔链表" 算法的示例代码:

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

public class PartitionList {
    public ListNode partition(ListNode head, int x) {
        ListNode lessThanX = new ListNode(0);
        ListNode greaterThanOrEqualX = new ListNode(0);
        ListNode lessThanXDummy = lessThanX;
        ListNode greaterThanOrEqualXDummy = greaterThanOrEqualX;

        while (head != null) {
            if (head.val < x) {
                lessThanX.next = head;
                lessThanX = lessThanX.next;
            } else {
                greaterThanOrEqualX.next = head;
                greaterThanOrEqualX = greaterThanOrEqualX.next;
            }
            head = head.next;
        }

        greaterThanOrEqualX.next = null;  // To prevent cyclic link

        lessThanX.next = greaterThanOrEqualXDummy.next;

        return lessThanXDummy.next;
    }
}

算法分析:

  • 时间复杂度:遍历一次原链表,将节点分别添加到两个新链表中,所以时间复杂度为 O(n),其中 n 是链表的长度。
  • 空间复杂度:算法使用了两个新的链表,所以空间复杂度为 O(n),其中 n 是链表的长度。

示例和测试:

假设给定链表 1 -> 4 -> 3 -> 2 -> 5 -> 2x = 3,根据算法,将链表分隔后得到 1 -> 2 -> 2 -> 4 -> 3 -> 5

我们可以使用以下代码进行测试:

public class Main {
    public static void main(String[] args) {
        PartitionList solution = new PartitionList();
        ListNode head = new ListNode(1);
        head.next = new ListNode(4);
        head.next.next = new ListNode(3);
        head.next.next.next = new ListNode(2);
        head.next.next.next.next = new ListNode(5);
        head.next.next.next.next.next = new ListNode(2);
        int x = 3;

        ListNode result = solution.partition(head, x);

        System.out.print("Resulting linked list: ");
        while (result != null) {
            System.out.print(result.val + " ");
            result = result.next;
        }
    }
}

总结:

"分隔链表" 算法题要求将链表中小于给定值 x 的节点移到大于等于 x 的节点之前,是一个关于链表操作的问题。通过实现这个算法,我们可以提升对链表操作的考虑,同时也能拓展对链表处理的能力。这个问题强调了如何维护两个新的链表,然后连接它们以重新组织链表中的节点。

标签: 编程算法, 编程算法题, 编程算法大全, 编程算法流程, 算法设计与分析, 数据结构与算法, 算法优化, 算法实现, 常见编程算法, 编程算法入门, 编程算法进阶, 编程算法精通