给定一个链表和一个特定值 x,对链表进行分隔,使得所有小于 x 的节点都在大于或等于 x 的节点之前。

分割链表:

题目如下:

给定一个链表和一个特定值 x,对链表进行分隔,使得所有小于 x 的节点都在大于或等于 x 的节点之前。

你应当保留两个分区中每个节点的初始相对位置。

示例:

输入: head = 1->4->3->2->5->2, x = 3
输出: 1->2->2->4->3->5

这个题是LeetCode第86题,我对本题的思路如下:
首先肯定保证时间复杂度在o(1),新建一个指针[引用],遍历链表,当前节点的值小于给定值,将其在当前链表中删除,插入另一个链表,也就是遍历完成之后一个链表是比最小值小的,一个链表是比最小值大的,因为比最小值小的那个链表在遍历过程中保留了尾指针,所以直接将这两个链表连接即可。

代码如下:

public static ListNode partition(ListNode head, int x) {
        //当链表为空或者链表中只有一个节点的时候,直接返回
        if (head == null || head.next == null)
            return head;
        //给当前的链表一个虚拟表头结点,在后续就可以不用判断节点是不是表头结点这个特殊情况
        ListNode tempHead = new ListNode(0);
        //新建一个存放比给定值小的链表的虚拟头结点
        ListNode minHead = new ListNode(0);
        tempHead.next = head;
        //p表示的是当前遍历的节点,pre是当前遍历节点的前一个节点,因为要删除,所以需要知道前一个节点
        //t是存放比给定值小的链表的尾节点
        ListNode p, pre = tempHead, t = minHead;
        for (p = head; p != null; ) {
            //当前值小于给定值
            if (p.val < x) {
                //删除当前值
                pre.next = p.next;
                p.next = null;
                //将其插入存放小值的链表的末尾
                t.next = p;
                t = t.next;
                //删除之后,p的位置是pre后面的位置
                p=pre.next;
            } else {
                //p和pre的位置也向后移
                pre=p;
                p = p.next;
            }
        }
        t.next = tempHead.next;
        return minHead.next;
    }

本函数在LeetCode上提交正确,无毒无害哟

贴一个完整的,给有需要的人:
 

public class Num86 {
    public static void main(String[] args) {
        int[] arr = {1, 4, 3, 2, 5, 2};
        ListNode head = new ListNode(arr);
        head = partition(head, 1);
        System.out.println(head.toString());
    }

    public static ListNode partition(ListNode head, int x) {
        //当链表为空或者链表中只有一个节点的时候,直接返回
        if (head == null || head.next == null)
            return head;
        //给当前的链表一个虚拟表头结点,在后续就可以不用判断节点是不是表头结点这个特殊情况
        ListNode tempHead = new ListNode(0);
        //新建一个存放比给定值小的链表的虚拟头结点
        ListNode minHead = new ListNode(0);
        tempHead.next = head;
        //p表示的是当前遍历的节点,pre是当前遍历节点的前一个节点,因为要删除,所以需要知道前一个节点
        //t是存放比给定值小的链表的尾节点
        ListNode p, pre = tempHead, t = minHead;
        for (p = head; p != null; ) {
            //当前值小于给定值
            if (p.val < x) {
                //删除当前值
                pre.next = p.next;
                p.next = null;
                //将其插入存放小值的链表的末尾
                t.next = p;
                t = t.next;
                //删除之后,p的位置是pre后面的位置
                p=pre.next;
            } else {
                //p和pre的位置也向后移
                pre=p;
                p = p.next;
            }
        }
        t.next = tempHead.next;
        return minHead.next;
    }

    static class ListNode {
        int val;
        ListNode next;

        ListNode(int x) {
            val = x;
        }

        public ListNode(int[] arr) {
            if (arr == null || arr.length == 0)
                throw new IllegalArgumentException("arr can to be empty");
            this.val = arr[0];
            ListNode cur = this;
            for (int i = 1; i < arr.length; i++) {
                cur.next = new ListNode(arr[i]);
                cur = cur.next;
            }
        }

        @Override
        public String toString() {
            StringBuilder res = new StringBuilder();
            ListNode cur = this;
            while (cur != null) {
                res.append(cur.val + "->");
                cur = cur.next;
            }
            res.append("NULL");
            return res.toString();
        }
    }
}

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值